package com.dl7.player.media;

import com.dl7.player.ResourceTable;
import com.dl7.player.danmaku.BiliDanmukuParser;
import com.dl7.player.danmaku.IntDef;
import com.dl7.player.danmaku.OnDanmakuListener;
import com.dl7.player.utils.*;
import com.dl7.player.widgets.ShareDialog;
import master.flame.danmaku.controller.IDanmakuView;
import master.flame.danmaku.danmaku.loader.ILoader;
import master.flame.danmaku.danmaku.loader.IllegalDataException;
import master.flame.danmaku.danmaku.loader.android.DanmakuLoaderFactory;
import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.DanmakuTimer;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.IDisplayer;
import master.flame.danmaku.danmaku.model.android.BaseCacheStuffer;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.model.android.SimpleTextCacheStuffer;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.danmaku.parser.IDataSource;
import master.flame.danmaku.ui.widget.DanmakuView;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.agp.animation.Animator;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.*;
import ohos.agp.window.dialog.IDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.*;
import ohos.app.Context;
import ohos.batterymanager.BatteryInfo;
import ohos.bundle.AbilityInfo;
import ohos.event.commonevent.*;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.configuration.Configuration;
import ohos.global.resource.*;
import ohos.media.audio.AudioManager;
import ohos.media.audio.AudioRemoteException;
import ohos.media.image.ImagePacker;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.photokit.metadata.AVMetadataHelper;
import ohos.multimodalinput.event.KeyEvent;
import ohos.multimodalinput.event.TouchEvent;
import ohos.net.NetManager;
import ohos.rpc.RemoteException;
import ohos.sysappcomponents.settings.SystemSettings;
import ohos.utils.PlainArray;
import ohos.utils.net.Uri;
import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

import java.io.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static com.dl7.player.utils.StringUtils.generateTime;
import static ohos.event.commonevent.CommonEventSupport.*;
import static tv.danmaku.ijk.media.player.IMediaPlayer.OnInfoListener;

/**
 * Created by long on 2016/10/24.
 */
public class IjkPlayerView extends StackLayout
        implements HandleTouchEvent.GestureEvent, Component.ClickedListener, AbsButton.CheckedStateChangedListener {

    // 进度条最大值
    private static final int MAX_VIDEO_SEEK = 980;
    // 默认隐藏控制栏时间
    private static final int DEFAULT_HIDE_TIMEOUT = 5000;
    // 更新进度消息
    private static final int MSG_UPDATE_SEEK = 10086;
    // 使能翻转消息
    private static final int MSG_ENABLE_ORIENTATION = 10087;
    // 尝试重连消息
    private static final int MSG_TRY_RELOAD = 10088;
    // 无效变量
    private static final int INVALID_VALUE = -1;
    // 达到文件时长的允许误差值，用来判断是否播放完成
    private static final int INTERVAL_TIME = 1000;

    // 原生的IjkPlayer
    private IjkVideoView mVideoView;
    // 视频开始前的缩略图，根据需要外部进行加载
    public Image mPlayerThumb;
    // 加载
    private ProgressBar mLoadingView;
    // 音量
    private Text mTvVolume;
    // 亮度
    private Text mTvBrightness;
    // 快进
    private Text mTvFastForward;
    //快退
    private Text mTvFastRewind;
    // 触摸信息布局
    private StackLayout mFlTouchLayout;
    // 全屏下的后退键
    private Image mIvBack;
    // 全屏下的标题
    private Text mTvTitle;
    // 全屏下的TopBar
    private DirectionalLayout mFullscreenTopBar;
    // 窗口模式的后退键
    private Image mIvBackWindow;
    // 窗口模式的TopBar
    private StackLayout mWindowTopBar;
    // 播放键
    private Image mIvPlay;
    private Image mIvPlayCircle;
    // 当前时间
    private Text mTvCurTime;
    // 进度条
    private Slider mPlayerSeek;
    // 结束时间
    private Text mTvEndTime;
    // 全屏切换按钮
    private Image mIvFullscreen;
    // BottomBar
    private DirectionalLayout mLlBottomBar;
    // 整个视频框架布局
    private StackLayout mFlVideoBox;
    // 锁屏键
    private Image mIvPlayerLock;
    // 还原屏幕
    private Text mTvRecoverScreen;
    // 宽高比选项
    private Text mTvSettings;
    private RadioContainer mAspectRatioOptions;
    // 关联的Activity
    private Ability mAttachActivity;
    // 重试
    private Text mTvReload;
    private Component mFlReload;

    private String mVideoPath;

    private EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner()) {
        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            LogUtil.error("IjkPlayerView.mHandler", "eventId: " + event.eventId);
            if (event.eventId == MSG_UPDATE_SEEK) {
                final int pos = _setProgress();
                if (!mIsSeeking && mIsShowBar && mVideoView.isPlaying()) {
                    // 这里会重复发送MSG，已达到实时更新 Seek 的效果
                    event = InnerEvent.get(MSG_UPDATE_SEEK);
                    sendEvent(event, 1000 - (pos % 1000));
                }
            } else if (event.eventId == MSG_ENABLE_ORIENTATION) {
//                if (mOrientationListener != null) {
//                    mOrientationListener.enable();
//                }
            } else if (event.eventId == MSG_TRY_RELOAD) {
                if (mIsNetConnected) {
                    reload();
                }
                event = InnerEvent.get(MSG_TRY_RELOAD);
                sendEvent(event, 3000);
            }
        }
    };

    // 音量控制
    private AudioManager mAudioManager;
    // 手势控制
    private TouchEventListener mGestureDetector;
    // 最大音量
    private int mMaxVolume;
    // 锁屏
    private boolean mIsForbidTouch = false;
    // 是否显示控制栏
    private boolean mIsShowBar = true;
    // 是否全屏
    private boolean mIsFullscreen;
    // 是否播放结束
    private boolean mIsPlayComplete = false;
    // 是否正在拖拽进度条
    private boolean mIsSeeking;
    // 目标进度
    private long mTargetPosition = INVALID_VALUE;
    // 当前进度
    private int mCurPosition = INVALID_VALUE;
    // 当前音量
    private int mCurVolume = INVALID_VALUE;
    // 当前亮度
    private float mCurBrightness = INVALID_VALUE;
    // 初始高度
    private int mInitHeight;
    // 屏幕宽/高度
    private int mWidthPixels;
    // 屏幕UI可见性
    private int mScreenUiVisibility;
    // 屏幕旋转角度监听
//    private OrientationEventListener mOrientationListener;
    // 进来还未播放
    private boolean mIsNeverPlay = true;
    // 外部监听器
    private OnInfoListener mOutsideInfoListener;
    private IMediaPlayer.OnCompletionListener mCompletionListener;
    // 禁止翻转，默认为禁止
    private boolean mIsForbidOrientation = true;
    // 是否固定全屏状态
    private boolean mIsAlwaysFullScreen = false;
    // 记录按退出全屏时间
    private long mExitTime = 0;
    // 视频Matrix
    private Matrix mVideoMatrix = new Matrix();
    private Matrix mSaveMatrix = new Matrix();
    // 是否需要显示恢复屏幕按钮
    private boolean mIsNeedRecoverScreen = false;
    // 选项列表高度
    private int mAspectOptionsHeight;
    // 异常中断时的播放进度
    private int mInterruptPosition;
    private boolean mIsReady = false;
    private Context mContext;
    private ComponentContainer mComponent;
    protected StackLayout videoView;
    private HandleTouchEvent handleTouchEvent;

    public IjkPlayerView(Context context) {
        this(context, null);
        this.mContext = context;
    }

    public IjkPlayerView(Context context, AttrSet attrs) {
        super(context, attrs);
        this.mContext = context;
        _initView(context);
    }

    // 是否是按下的标识，默认为其他动作，true为按下标识，false为其他动作
    private boolean isDownTouch;
    // 是否声音控制,默认为亮度控制，true为声音控制，false为亮度控制
    private boolean isVolume;
    // 是否横向滑动，默认为纵向滑动，true为横向滑动，false为纵向滑动
    private boolean isLandscape;
    // 是否从弹幕编辑状态返回
    private boolean isRecoverFromDanmaku;
    //是否第一次按下
    private boolean isFirstDownTouch = true;

    //是否第二次按下
    private boolean isDoubleDownTouch = false;
    //是否滑动
    private boolean isScroll = false;

    //起始位置
    float mOldX = 0;
    float mOldY = 0;

    //结束位置
    float mEndX = 0;
    float mEndY = 0;
    // 记录第一次点击事件
    private long mFirstTouch = 0;


    private void _initView(Context context) {
        if (context instanceof Ability) {
            mAttachActivity = (Ability) context;
        } else {
            throw new IllegalArgumentException("Context must be AppCompatActivity");
        }
        handleTouchEvent = new HandleTouchEvent(this);
        videoView = new StackLayout(getContext());
        mComponent = (ComponentContainer) LayoutScatter
                .getInstance(context)
                .parse(ResourceTable.Layout_layout_player_view, this, false);
        videoView.addComponent(mComponent, new StackLayout.LayoutConfig(-1, -1));
        addComponent(videoView, new StackLayout.LayoutConfig(-1, -1));

        mVideoView = (IjkVideoView) findComponentById(ResourceTable.Id_video_view);
        mPlayerThumb = (Image) findComponentById(ResourceTable.Id_iv_thumb);
        mLoadingView = (ProgressBar) findComponentById(ResourceTable.Id_pb_loading);
        mFlVideoBox = (StackLayout) findComponentById(ResourceTable.Id_fl_video_box);
        mIvPlayerLock = (Image) findComponentById(ResourceTable.Id_iv_player_lock);
        mIvPlayCircle = (Image) findComponentById(ResourceTable.Id_iv_play_circle);
        mTvReload = (Text) findComponentById(ResourceTable.Id_tv_reload);
        mFlReload = findComponentById(ResourceTable.Id_fl_reload_layout);

        _initTopBar();
        _initBottomBar();
        _initTouchGestures();
        _initMediaQuality();
        _initVideoSkip();
        _initReceiver(context);
        initDanmakuView();

        mIvPlay.setClickedListener(this);
        mIvBack.setClickedListener(this);
        mIvFullscreen.setClickedListener(this);
        mIvBackWindow.setClickedListener(this);
        mIvPlayerLock.setClickedListener(this);
        mIvPlayCircle.setClickedListener(this);
        mTvRecoverScreen.setClickedListener(this);
        mTvSettings.setClickedListener(this);
        mTvReload.setClickedListener(this);

        mVideoView.setDraggedListener(Component.DRAG_HORIZONTAL_VERTICAL, new DraggedListener() {
            @Override
            public void onDragDown(Component component, DragInfo dragInfo) {
                LogUtil.error("IjkPlayerView.setDraggedListener", "onDragDown: ");
                handleTouchEvent.handleEvent(component
                        , dragInfo, HandleTouchEvent.TOUCH_STATUS_DOWN);
                isDownTouch = true;
                isRecoverFromDanmaku = recoverFromEditVideo();

                LogUtil.error("IjkPlayerView.setDraggedListener"
                        , "isFirstDownTouch: " + isFirstDownTouch);
                LogUtil.error("IjkPlayerView.setDraggedListener"
                        , "isDoubleDownTouch: " + isDoubleDownTouch);

                if (System.currentTimeMillis() - mFirstTouch > 500) {
                    mFirstTouch = System.currentTimeMillis();
                    isFirstDownTouch = true;
                    isDoubleDownTouch = false;
                } else {
                    mFirstTouch = 0;
                    isFirstDownTouch = false;
                    isDoubleDownTouch = true;
                }


                if (isFirstDownTouch || !isScroll) {
                    // 弹幕编辑状态返回则不执行单击操作
                    if (isRecoverFromDanmaku) {
                    }

                    if (mIsShowQuality) {
                        _toggleMediaQuality();
                    } else {
                        _toggleControlBar();
                    }
                } else if (isDoubleDownTouch) {
                    // 如果未进行播放或从弹幕编辑状态返回则不执行双击操作
                    if (mIsNeverPlay || isRecoverFromDanmaku) {

                    }
                    if (!mIsForbidTouch) {
                        _refreshHideRunnable();
                        _togglePlayStatus();
                    }
                }

            }

            @Override
            public void onDragStart(Component component, DragInfo dragInfo) {
                LogUtil.error("IjkPlayerView.setDraggedListener", "onDragStart: ");
                isScroll = true;

            }

            @Override
            public void onDragUpdate(Component component, DragInfo dragInfo) {
                LogUtil.error("IjkPlayerView.setDraggedListener", "onDragUpdate: ");
                handleTouchEvent.handleEvent(component
                        , dragInfo, HandleTouchEvent.TOUCH_STATUS_MOVE);

                isScroll = true;
            }

            @Override
            public void onDragEnd(Component component, DragInfo dragInfo) {
                LogUtil.error("IjkPlayerView.setDraggedListener", "onDragEnd: ");
                handleTouchEvent.handleEvent(component
                        , dragInfo, HandleTouchEvent.TOUCH_STATUS_END);
                isScroll = false;
            }

            @Override
            public void onDragCancel(Component component, DragInfo dragInfo) {
                LogUtil.error("IjkPlayerView.setDraggedListener"
                        , "onDragCancel: ");
                handleTouchEvent.handleEvent(component
                        , dragInfo, HandleTouchEvent.TOUCH_STATUS_END);
            }
        });
    }


    private RadioButton fitScreen;
    private RadioButton fillParent;
    private RadioButton fit4and3;
    private RadioButton fit16and9;
    private RadioContainer radioContainer;

    /**
     * 初始化顶部状态栏控制
     */
    private void _initTopBar() {
        //layout_top_bar
        mIvBack = (Image) findComponentById(ResourceTable.Id_iv_back);
        mTvTitle = (Text) findComponentById(ResourceTable.Id_tv_title);
        mFullscreenTopBar = (DirectionalLayout) findComponentById(ResourceTable.Id_fullscreen_top_bar);
        mIvBackWindow = (Image) findComponentById(ResourceTable.Id_iv_back_window);
        mWindowTopBar = (StackLayout) findComponentById(ResourceTable.Id_window_top_bar);
        // 视频宽高比设置
        mTvSettings = (Text) findComponentById(ResourceTable.Id_tv_settings);
        mAspectRatioOptions = (RadioContainer) findComponentById(ResourceTable.Id_aspect_ratio_group);
        //mAspectOptionsHeight = getResources().getDimensionPixelSize(30) * 4;
        mAspectOptionsHeight = (90) * 4;

        fitScreen = (RadioButton) findComponentById(ResourceTable.Id_aspect_fit_screen);
        fillParent = (RadioButton) findComponentById(ResourceTable.Id_aspect_fit_parent);
        fit4and3 = (RadioButton) findComponentById(ResourceTable.Id_aspect_4_and_3);
        fit16and9 = (RadioButton) findComponentById(ResourceTable.Id_aspect_16_and_9);

        fitScreen.setCheckedStateChangedListener(this);
        fillParent.setCheckedStateChangedListener(this);
        fit4and3.setCheckedStateChangedListener(this);
        fit16and9.setCheckedStateChangedListener(this);

        mAspectRatioOptions.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
            @Override
            public void onCheckedChanged(RadioContainer radioContainer, int checkedId) {
                if (checkedId == ResourceTable.Id_aspect_fit_parent) {
                    mVideoView.setAspectRatio(IRenderView.AR_ASPECT_FIT_PARENT);
                } else if (checkedId == ResourceTable.Id_aspect_fit_screen) {
                    mVideoView.setAspectRatio(IRenderView.AR_ASPECT_FILL_PARENT);
                } else if (checkedId == ResourceTable.Id_aspect_16_and_9) {
                    mVideoView.setAspectRatio(IRenderView.AR_16_9_FIT_PARENT);
                } else if (checkedId == ResourceTable.Id_aspect_4_and_3) {
                    mVideoView.setAspectRatio(IRenderView.AR_4_3_FIT_PARENT);
                }

//                mAspectRatioOptions.setHeight(mAspectOptionsHeight);
                AnimHelper.doClipViewHeight(mAspectRatioOptions, mAspectOptionsHeight, 0, 150);
            }
        });
    }

    @Override
    public void onCheckedChanged(AbsButton absButton, boolean checked) {
        if (absButton.getId() == ResourceTable.Id_aspect_fit_parent) {
            try {
                if (checked) {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_adjust_screen_checked);
                    PixelMapElement element = new PixelMapElement(resource);
                    fillParent.setBackground(element);
                } else {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_adjust_screen);
                    PixelMapElement element = new PixelMapElement(resource);
                    fillParent.setBackground(element);
                }
            } catch (IOException | NotExistException e) {
                e.printStackTrace();
            }
        } else if (absButton.getId() == ResourceTable.Id_aspect_fit_screen) {

            try {
                if (checked) {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_adjust_video_checked);
                    PixelMapElement element = new PixelMapElement(resource);
                    fitScreen.setBackground(element);
                } else {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_adjust_video);
                    PixelMapElement element = new PixelMapElement(resource);
                    fitScreen.setBackground(element);
                }
            } catch (IOException | NotExistException e) {
                e.printStackTrace();
            }

        } else if (absButton.getId() == ResourceTable.Id_aspect_16_and_9) {
            try {
                if (checked) {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_16_9_inside_checked);
                    PixelMapElement element = new PixelMapElement(resource);
                    fit16and9.setBackground(element);
                } else {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_16_9_inside);
                    PixelMapElement element = new PixelMapElement(resource);
                    fit16and9.setBackground(element);
                }

            } catch (IOException | NotExistException e) {
                e.printStackTrace();
            }

        } else if (absButton.getId() == ResourceTable.Id_aspect_4_and_3) {

            try {
                if (checked) {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_4_3_inside_checked);
                    PixelMapElement element = new PixelMapElement(resource);
                    fit4and3.setBackground(element);
                } else {
                    Resource resource = getResourceManager()
                            .getResource(ResourceTable.Media_ic_ar_4_3_inside);
                    PixelMapElement element = new PixelMapElement(resource);
                    fit4and3.setBackground(element);
                }

            } catch (IOException | NotExistException e) {
                e.printStackTrace();
            }
        }
        mAspectRatioOptions.setVisibility(HIDE);

    }

    /**
     * 初始化底部控制栏
     */
    private void _initBottomBar() {
        mIvPlay = (Image) findComponentById(ResourceTable.Id_iv_play);
        mTvCurTime = (Text) findComponentById(ResourceTable.Id_tv_cur_time);
        mPlayerSeek = (Slider) findComponentById(ResourceTable.Id_player_seek);
        mTvEndTime = (Text) findComponentById(ResourceTable.Id_tv_end_time);
        mIvFullscreen = (Image) findComponentById(ResourceTable.Id_iv_fullscreen);
        mLlBottomBar
                = (DirectionalLayout) findComponentById(ResourceTable.Id_ll_bottom_bar);
        mTvRecoverScreen = (Text) findComponentById(ResourceTable.Id_tv_recover_screen);
    }

    /**
     * 初始化声音，亮度，进度控制
     */
    private void _initTouchGestures() {
        //layout_touch_gestures
        mTvVolume = (Text) findComponentById(ResourceTable.Id_tv_volume);
        mTvBrightness = (Text) findComponentById(ResourceTable.Id_tv_brightness);
        mTvFastForward = (Text) findComponentById(ResourceTable.Id_tv_fast_forward);
        mTvFastRewind = (Text) findComponentById(ResourceTable.Id_tv_fast_rewind);
        mFlTouchLayout = (StackLayout) findComponentById(ResourceTable.Id_fl_touch_layout);
    }

    /**
     * 初始化
     */
    private void _initMediaPlayer() {
        // 加载 IjkMediaPlayer 库
        IjkMediaPlayer.loadLibrariesOnce(null);
        IjkMediaPlayer.native_profileBegin("libijkplayer.so");
        // 声音
        mAudioManager = new AudioManager(getContext());

        try {
            mMaxVolume = mAudioManager.getMaxVolume(AudioManager.AudioVolumeType.STREAM_MUSIC);
        } catch (AudioRemoteException e) {
            e.printStackTrace();
        }
        // 亮度
        int e = (int) mAttachActivity.getWindow().getLayoutConfig().get().windowBrightness;
        float progress = 1.0F * (float) e / 255.0F;
        WindowManager.LayoutConfig layout = mAttachActivity.getWindow().getLayoutConfig().get();
        layout.windowBrightness = progress;
        mAttachActivity.getWindow().setLayoutConfig(layout);
        // 进度
        mPlayerSeek.setMaxValue(MAX_VIDEO_SEEK);
        mPlayerSeek.setValueChangedListener(mSeekListener);
        // 视频监听
        mVideoView.setOnInfoListener(mInfoListener);

        mFlVideoBox.setClickable(true);
        mFlVideoBox.setTouchEventListener(mPlayerTouchListener);
        // 屏幕翻转控制
//        mOrientationListener = new OrientationEventListener(mAttachActivity) {
//            @Override
//            public void onOrientationChanged(int orientation) {
//                _handleOrientation(orientation);
//            }
//        };
        if (mIsForbidOrientation) {
            // 禁止翻转
//            mOrientationListener.disable();
        }

        this.setArrangeListener(new ArrangeListener() {
            @Override
            public boolean onArrange(int i, int i1, int i2, int i3) {
                if (mInitHeight == 0) {
                    mInitHeight = getHeight();
                    mWidthPixels = mAttachActivity.getWindow().getLayoutConfig().get().width;
                }
                return false;
            }
        });
    }


    /**============================ 外部调用接口 ============================*/

    /**
     * Activity.onResume() 里调用
     */
    public void onResume() {
        if (mIsScreenLocked) {
            // 如果出现锁屏则需要重新渲染器Render，不然会出现只有声音没有动画
            // 目前只在锁屏时会出现图像不动的情况，如果有遇到类似情况可以尝试按这个方法解决
            mVideoView.setRender(IjkVideoView.RENDER_TEXTURE_VIEW);
            mIsScreenLocked = false;
        }
        mVideoView.resume();
        if (!mIsForbidTouch && !mIsForbidOrientation) {
//            mOrientationListener.enable();
        }
        if (mCurPosition != INVALID_VALUE) {
            // 重进后 seekTo 到指定位置播放时，通常会回退到前几秒，关键帧??
            seekTo(mCurPosition);
            mCurPosition = INVALID_VALUE;
        }
    }

    /**
     * Activity.onPause() 里调用
     */
    public void onPause() {
        mCurPosition = mVideoView.getCurrentPosition();
        mVideoView.pause();
        mDanmakuView.pause();
        mIvPlay.setSelected(false);
        mIvPlay.setPixelMap(ResourceTable.Media_ic_video_play);
//        mOrientationListener.disable();
//        屏蔽弹幕功能
//        _pauseDanmaku();
    }

    /**
     * Activity.onDestroy() 里调用
     *
     * @return 返回播放进度
     */
    public int onDestroy() {
        // 记录播放进度
        int curPosition = mVideoView.getCurrentPosition();
        mVideoView.destroy();
        IjkMediaPlayer.native_profileEnd();
//        屏蔽弹幕功能
//        if (mDanmakuView != null) {
//            // don't forget release!
//            mDanmakuView.release();
//            mDanmakuView = null;
//        }
        if (mShareDialog != null) {
//            mShareDialog.dismiss();
            mShareDialog = null;
        }
        mHandler.removeEvent(MSG_TRY_RELOAD);
        mHandler.removeEvent(MSG_UPDATE_SEEK);
        // 注销广播
        unsubscribeVoiceEvents();
        try {
            CommonEventManager.unsubscribeCommonEvent(mBatteryReceiver);
            CommonEventManager.unsubscribeCommonEvent(mScreenReceiver);
            CommonEventManager.unsubscribeCommonEvent(mNetReceiver);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        // 关闭屏幕常亮
        mAttachActivity.getWindow().clearFlags(WindowManager.LayoutConfig.MARK_SCREEN_ON_ALWAYS);
        return curPosition;
    }

    /**
     * 处理音量键，避免外部按音量键后导航栏和状态栏显示出来退不回去的状态
     *
     * @param keyCode
     * @return
     */
    public boolean handleVolumeKey(int keyCode) {
        if (keyCode == KeyEvent.KEY_VOLUME_UP) {
            _setVolume(true);
            return true;
        } else if (keyCode == KeyEvent.KEY_VOLUME_DOWN) {
            _setVolume(false);
            return true;
        } else {
            return false;
        }
    }

    /**
     * 回退，全屏时退回竖屏
     *
     * @return
     */
    public boolean onBackPressed() {
        if (recoverFromEditVideo()) {
            return true;
        }
        if (mIsAlwaysFullScreen) {
            _exit();
            return true;
        } else if (mIsFullscreen) {
            mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
            if (mIsForbidTouch) {
                // 锁住状态则解锁
                mIsForbidTouch = false;
                mIvPlayerLock.setSelected(false);
                _setControlBarVisible(mIsShowBar);
            }
            return true;
        }
        return false;
    }

    /**
     * 初始化，必须要先调用
     *
     * @return
     */
    public IjkPlayerView init() {
        _initMediaPlayer();
        return this;
    }

    /**
     * 切换视频
     *
     * @param url
     * @return
     */
    public IjkPlayerView switchVideoPath(String url) {
        return switchVideoPath(Uri.parse(url));
    }

    /**
     * 切换视频
     *
     * @param uri
     * @return
     */
    public IjkPlayerView switchVideoPath(Uri uri) {
        if (mQualityData != null) {
            mQualityData.clear();
            mQualityData = null;
        }
        reset();
        return setVideoPath(uri);
    }

    /**
     * 设置播放资源
     *
     * @param url
     * @return
     */
    public IjkPlayerView setVideoPath(String url) {
        LogUtil.error("IjkPlayerView.setVideoPath", "url: " + url);
        mVideoPath = url;
        return setVideoPath(Uri.parse(url));
    }


    /**
     * 设置播放资源
     *
     * @param uri
     * @return
     */
    public IjkPlayerView setVideoPath(Uri uri) {
        LogUtil.error("IjkPlayerView.setVideoPath", "uri: " + uri);
        mVideoView.setVideoURI(uri);
        if (mCurPosition != INVALID_VALUE) {
            seekTo(mCurPosition);
            mCurPosition = INVALID_VALUE;
        } else {
            seekTo(0);
        }
        return this;
    }

    /**
     * 设置标题，全屏的时候可见
     *
     * @param title
     */
    public IjkPlayerView setTitle(String title) {
        mTvTitle.setText(title);
        // 跑马灯效果
        mTvTitle.setTruncationMode(Text.TruncationMode.AUTO_SCROLLING);
        // 始终处于自动滚动状态
        mTvTitle.setAutoScrollingCount(Text.AUTO_SCROLLING_FOREVER);
        // 启动跑马灯效果
        mTvTitle.startAutoScrolling();
        return this;
    }

    /**
     * 设置只显示全屏状态
     */
    public IjkPlayerView alwaysFullScreen() {
        mIsAlwaysFullScreen = true;
        _setFullScreen(true);
        mIvFullscreen.setVisibility(HIDE);
        mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
        _setUiLayoutFullscreen();
        return this;
    }

    /**
     * 设置普通模式进入全屏状态
     */
    public IjkPlayerView enterNormalFullScreen() {
        ComponentContainer componentContainer = (ComponentContainer) videoView.getComponentParent();
        if (componentContainer != null) {
            componentContainer.removeComponent(videoView);
            Display display = DisplayManager.getInstance().getAllDisplays(mAttachActivity).get(0);
            DisplayAttributes attributes = display.getAttributes();
            int height = Math.min(attributes.width, attributes.height);
            int width = Math.max(attributes.width, attributes.height);
            componentContainer.setLayoutConfig(new LayoutConfig(width, height));
            componentContainer.addComponent(videoView, new LayoutConfig(-1, -1));
            SurfaceRenderView renderView = new SurfaceRenderView(getContext());
            renderView.setVideoSize(width, height);
            mVideoView.setRenderView(renderView);
        }
        return this;
    }

    /**
     * 设置普通模式退出全屏状态
     */
    public IjkPlayerView quiteNormalFullScreen() {
        ComponentContainer componentContainer = (ComponentContainer) videoView.getComponentParent();
        if (componentContainer != null) {
            componentContainer.removeComponent(videoView);
        }
        Display display = DisplayManager.getInstance().getAllDisplays(mAttachActivity).get(0);
        DisplayAttributes attributes = display.getAttributes();
        int height = Math.min(attributes.width, attributes.height);
        int width = Math.max(attributes.width, attributes.height);

        SurfaceRenderView renderView = new SurfaceRenderView(getContext());
        LogUtil.error("IjkPlayerView.quiteNormalFullScreen", "mAttachActivity.getDisplayOrientation(): " + mAttachActivity.getDisplayOrientation());
        if (mAttachActivity.getDisplayOrientation() == 0) {
            componentContainer.setLayoutConfig(new LayoutConfig(width, -1));
        } else {
            componentContainer.setLayoutConfig(new LayoutConfig(height, 600));
        }
        componentContainer.addComponent(videoView);
        mVideoView.setRenderView(renderView);
        return this;
    }

    /**
     * 开始播放
     *
     * @return
     */
    public void start() {
        if (mIsPlayComplete) {
//            屏蔽弹幕功能
//            if (mDanmakuView != null && mDanmakuView.isPrepared()) {
//                mDanmakuView.seekTo((long) 0);
//                mDanmakuView.pause();
//            }
            mIsPlayComplete = false;
        }
        if (!mVideoView.isPlaying()) {
            mIvPlay.setSelected(true);
            mIvPlay.setPixelMap(ResourceTable.Media_ic_video_pause);
            mVideoView.start();
            // 更新进度
            mHandler.sendEvent(MSG_UPDATE_SEEK);
        }
        LogUtil.info("IjkPlayerView.start", "mIsNeverPlay: " + mIsNeverPlay);
        if (mIsNeverPlay) {
            mIsNeverPlay = false;
            mIvPlayCircle.setVisibility(HIDE);
            mLoadingView.setVisibility(VISIBLE);
            mIsShowBar = false;
            // 放这边装载弹幕，不然会莫名其妙出现多切几次到首页会弹幕自动播放问题，这里处理下
//            _loadDanmaku();
        }
        // 视频播放时开启屏幕常亮
        mAttachActivity.getWindow().addFlags(WindowManager.LayoutConfig.MARK_SCREEN_ON_ALWAYS);
    }

    /**
     * 重新开始
     */
    public void reload() {
        mFlReload.setVisibility(HIDE);
        mLoadingView.setVisibility(VISIBLE);
        if (mIsReady) {
            // 确保网络正常时
            if (NetWorkUtils.isNetworkAvailable(mAttachActivity)) {
                mVideoView.reload();
                mVideoView.start();
//                start();
                if (mInterruptPosition > 0) {
                    seekTo(mInterruptPosition);
                    mInterruptPosition = 0;
                }
            }
        } else {
            mVideoView.release(false);
            mVideoView.setRender(IjkVideoView.RENDER_TEXTURE_VIEW);
            start();
        }
        // 更新进度
        mHandler.removeEvent(MSG_UPDATE_SEEK);
        mHandler.sendEvent(MSG_UPDATE_SEEK);
    }

    /**
     * 是否正在播放
     *
     * @return
     */
    public boolean isPlaying() {
        return mVideoView.isPlaying();
    }

    /**
     * 暂停
     */
    public void pause() {
        mIvPlay.setSelected(false);
        mDanmakuView.pause();
        mIvPlay.setPixelMap(ResourceTable.Media_ic_video_play);
        mDanmakuView.pause();
        if (mVideoView.isPlaying()) {
            mVideoView.pause();
        }
//        屏蔽弹幕功能
//        _pauseDanmaku();
        // 视频暂停时关闭屏幕常亮
        mAttachActivity.getWindow().clearFlags(WindowManager.LayoutConfig.MARK_SCREEN_ON_ALWAYS);
    }

    /**
     * 跳转
     *
     * @param position 位置
     */
    public void seekTo(int position) {
        mVideoView.seekTo(position);
        //屏蔽弹幕功能
//        mDanmakuTargetPosition = position;
    }

    /**
     * 停止
     */
    public void stop() {
        pause();
        mVideoView.stopPlayback();
    }

    /**
     * 重置状态
     */
    public void reset() {
//屏蔽弹幕功能
//        if (mIsEnableDanmaku && mDanmakuView != null) {
//            _toggleDanmakuView(false);
//            mDanmakuView.release();
//            mDanmakuView = null;
//            mIsEnableDanmaku = false;
//        }
        mIsNeverPlay = true;
        mCurPosition = 0;
        stop();
        mVideoView.setRender(IjkVideoView.RENDER_TEXTURE_VIEW);
    }

    /**============================ 控制栏处理 ============================*/

    /**
     * SeekBar监听
     */
    private final Slider.ValueChangedListener mSeekListener = new Slider.ValueChangedListener() {
        private long curPosition;

        @Override
        public void onProgressUpdated(Slider slider, int progress, boolean fromUser) {
            if (!fromUser) {
                // We're not interested in programmatically generated changes to
                // the progress bar's position.
                return;
            }
            long duration = mVideoView.getDuration();
            // 计算目标位置
            mTargetPosition = (duration * progress) / MAX_VIDEO_SEEK;
            int deltaTime = (int) ((mTargetPosition - curPosition) / 1000);
            String desc;
            // 对比当前位置来显示快进或后退
            if (mTargetPosition > curPosition) {
                desc = generateTime(mTargetPosition) + "/"
                        + generateTime(duration) + "\n" + "+" + deltaTime + "秒";
                _setFastForward(desc);
            } else {
                desc = generateTime(mTargetPosition) + "/"
                        + generateTime(duration) + "\n" + deltaTime + "秒";
                _setFastRewind(desc);
            }
        }

        @Override
        public void onTouchStart(Slider slider) {
            mIsSeeking = true;
            _showControlBar(3600000);
            mHandler.removeEvent(MSG_UPDATE_SEEK);
            curPosition = mVideoView.getCurrentPosition();
        }

        @Override
        public void onTouchEnd(Slider slider) {
            _hideTouchView();
            mIsSeeking = false;
            // 视频跳转
            seekTo((int) mTargetPosition);
            mTargetPosition = INVALID_VALUE;
            _setProgress();
            _showControlBar(DEFAULT_HIDE_TIMEOUT);
        }

    };

    /**
     * 隐藏视图Runnable
     */
    private Runnable mHideBarRunnable = new Runnable() {
        @Override
        public void run() {
            _hideAllView(false);
        }
    };

    /**
     * 隐藏除视频外所有视图
     */
    private void _hideAllView(boolean isTouchLock) {
        LogUtil.info("IjkPlayerView._hideAllView", "_hideAllView ");
        mPlayerThumb.setVisibility(HIDE);
        mFlTouchLayout.setVisibility(HIDE);
        mFullscreenTopBar.setVisibility(HIDE);
        mWindowTopBar.setVisibility(HIDE);
        mLlBottomBar.setVisibility(HIDE);
        mAspectRatioOptions.setVisibility(HIDE);
        _showAspectRatioOptions(false);
        if (!isTouchLock) {
            mIvPlayerLock.setVisibility(HIDE);
            mIsShowBar = false;
        }
//        屏蔽弹幕功能
        if (mIsEnableDanmaku) {
            mDanmakuPlayerSeek.setVisibility(HIDE);
        }
        if (mIsNeedRecoverScreen) {
            mTvRecoverScreen.setVisibility(HIDE);
        }
    }

    /**
     * 设置控制栏显示或隐藏
     *
     * @param isShowBar
     */
    private void _setControlBarVisible(boolean isShowBar) {
        if (mIsNeverPlay) {
            mIvPlayCircle.setVisibility(isShowBar ? VISIBLE : HIDE);
        } else if (mIsForbidTouch) {
            mIvPlayerLock.setVisibility(isShowBar ? VISIBLE : HIDE);
        } else {
            mLlBottomBar.setVisibility(isShowBar ? VISIBLE : HIDE);
            if (!isShowBar) {
                _showAspectRatioOptions(false);
            }
            // 全屏切换显示的控制栏不一样
            if (mIsFullscreen) {
                // 只在显示控制栏的时候才设置时间，因为控制栏通常不显示且单位为分钟，所以不做实时更新
                mTvSystemTime.setText(StringUtils.getCurFormatTime());
                mFullscreenTopBar.setVisibility(isShowBar ? VISIBLE : HIDE);
                mWindowTopBar.setVisibility(HIDE);
                mIvPlayerLock.setVisibility(isShowBar ? VISIBLE : HIDE);
                //屏蔽弹幕功能
                if (mIsEnableDanmaku) {
                    mDanmakuPlayerSeek.setVisibility(isShowBar ? VISIBLE : HIDE);
                }
                if (mIsNeedRecoverScreen) {
                    mTvRecoverScreen.setVisibility(isShowBar ? VISIBLE : HIDE);
                }
            } else {
                mWindowTopBar.setVisibility(isShowBar ? VISIBLE : HIDE);
                mFullscreenTopBar.setVisibility(HIDE);
                mIvPlayerLock.setVisibility(HIDE);
//                屏蔽弹幕功能
                if (mIsEnableDanmaku) {
                    mDanmakuPlayerSeek.setVisibility(HIDE);
                }
                if (mIsNeedRecoverScreen) {
                    mTvRecoverScreen.setVisibility(HIDE);
                }
            }
        }
    }

    /**
     * 开关控制栏，单击界面的时候
     */
    private void _toggleControlBar() {
        mIsShowBar = !mIsShowBar;
        mIsShowBar = true;
        _setControlBarVisible(mIsShowBar);
        if (mIsShowBar) {
            // 发送延迟隐藏控制栏的操作
            mHandler.postTask(mHideBarRunnable, DEFAULT_HIDE_TIMEOUT);
            // 发送更新 Seek 消息
            mHandler.sendEvent(MSG_UPDATE_SEEK);
        }
    }

    /**
     * 显示控制栏
     *
     * @param timeout 延迟隐藏时间
     */
    private void _showControlBar(int timeout) {
        if (!mIsShowBar) {
            _setProgress();
            mIsShowBar = true;
        }
        _setControlBarVisible(true);
        mHandler.sendEvent(MSG_UPDATE_SEEK);
        // 先移除隐藏控制栏 Runnable，如果 timeout=0 则不做延迟隐藏操作
        mHandler.removeTask(mHideBarRunnable);
        if (timeout != 0) {
            mHandler.postTask(mHideBarRunnable, timeout);
        }
    }

    /**
     * 切换播放状态，点击播放按钮时
     */
    private void _togglePlayStatus() {
        if (mVideoView.isPlaying()) {
            pause();
            mIvPlay.setPixelMap(ResourceTable.Media_ic_video_play);
            mIvPlayCircle.setPixelMap(ResourceTable.Media_ic_play_circle);
        } else {
            start();
            mIvPlay.setPixelMap(ResourceTable.Media_ic_video_pause);
            mIvPlayCircle.setPixelMap(ResourceTable.Media_ic_player_lock);
        }
    }

    /**
     * 刷新隐藏控制栏的操作
     */
    private void _refreshHideRunnable() {
        mHandler.removeTask(mHideBarRunnable);
        mHandler.postTask(mHideBarRunnable, DEFAULT_HIDE_TIMEOUT);
    }

    /**
     * 切换控制锁
     */
    private void _togglePlayerLock() {
        mIsForbidTouch = !mIsForbidTouch;
        mIvPlayerLock.setSelected(mIsForbidTouch);
        if (mIsForbidTouch) {
            mIvPlayerLock.setPixelMap(ResourceTable.Media_ic_player_lock);
//            mOrientationListener.disable();
            _hideAllView(true);
        } else {
            mIvPlayerLock.setPixelMap(ResourceTable.Media_ic_player_unlock);
            if (!mIsForbidOrientation) {
//                mOrientationListener.enable();
            }
            mFullscreenTopBar.setVisibility(VISIBLE);
            mLlBottomBar.setVisibility(VISIBLE);
//            屏蔽弹幕功能
            if (mIsEnableDanmaku) {
                mDanmakuPlayerSeek.setVisibility(VISIBLE);
            }
            if (mIsNeedRecoverScreen) {
                mTvRecoverScreen.setVisibility(VISIBLE);
            }
        }
    }

    /**
     * 切换视频分辨率控制
     */
    private void _toggleMediaQuality() {
        if (mFlMediaQuality.getVisibility() == HIDE) {
            mFlMediaQuality.setVisibility(VISIBLE);
        }
        if (mIsShowQuality) {
            mFlMediaQuality.createAnimatorProperty().moveFromX(mFlMediaQuality.getWidth()).setDuration(DEFAULT_QUALITY_TIME);
            mIsShowQuality = false;
        } else {
            mFlMediaQuality.createAnimatorProperty().moveFromX(0).setDuration(DEFAULT_QUALITY_TIME);
            mIsShowQuality = true;
        }
    }

    /**
     * 显示宽高比设置
     *
     * @param isShow
     */
    private void _showAspectRatioOptions(boolean isShow) {
        if (isShow) {
            AnimHelper.doClipViewHeight(mAspectRatioOptions, 0, mAspectOptionsHeight, 150);
        } else {
            ComponentContainer.LayoutConfig layoutParams = mAspectRatioOptions.getLayoutConfig();
            layoutParams.height = 0;
        }
    }

    @Override
    public void onClick(Component component) {
        _refreshHideRunnable();
        int id = component.getId();
        if (id == ResourceTable.Id_iv_back) {
            if (mIsAlwaysFullScreen) {
                _exit();
                return;
            }
            mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
        } else if (id == ResourceTable.Id_iv_back_window) {
            mAttachActivity.terminateAbility();
        } else if (id == ResourceTable.Id_iv_play || id == ResourceTable.Id_iv_play_circle) {
            _togglePlayStatus();
        } else if (id == ResourceTable.Id_iv_fullscreen) {
            new ToastDialog(getContext()).setText("click fullScreen").show();
            _toggleFullScreen();
        } else if (id == ResourceTable.Id_iv_player_lock) {
            _togglePlayerLock();
        } else if (id == ResourceTable.Id_iv_media_quality) {
            new ToastDialog(getContext()).setText("click Quality").show();
            if (!mIsShowQuality) {
                _toggleMediaQuality();
            }
        } else if (id == ResourceTable.Id_iv_cancel_skip) {
            mHandler.removeTask(mHideSkipTipRunnable);
            _hideSkipTip();
        } else if (id == ResourceTable.Id_tv_do_skip) {
            mLoadingView.setVisibility(VISIBLE);
            // 视频跳转
            seekTo(mSkipPosition);
            mHandler.removeTask(mHideSkipTipRunnable);
            _hideSkipTip();
            _setProgress();
        } else if (id == ResourceTable.Id_iv_danmaku_control) {
//            屏蔽弹幕功能
//            _toggleDanmakuShow();
        } else if (id == ResourceTable.Id_tv_open_edit_danmaku) {
//            屏蔽弹幕功能
//            if (mDanmakuListener == null || mDanmakuListener.isValid()) {
//                editVideo();
//                mEditDanmakuLayout.setVisibility(VISIBLE);
//                SoftInputUtils.setEditFocusable(mAttachActivity, mEtDanmakuContent);
//            }
        } else if (id == ResourceTable.Id_iv_cancel_send) {
            recoverFromEditVideo();
        } else if (id == ResourceTable.Id_iv_do_send) {
            recoverFromEditVideo();
//            屏蔽弹幕功能
//            sendDanmaku(mEtDanmakuContent.getText().toString(), false);
//            mEtDanmakuContent.setText("");
        } else if (id == ResourceTable.String_input_options_more) {
//            屏蔽弹幕功能
//            _toggleMoreColorOptions();
        } else if (id == ResourceTable.Id_iv_screenshot) {
            _doScreenshot();
        } else if (id == ResourceTable.Id_tv_recover_screen) {
            mVideoView.resetVideoView(true);
            mIsNeedRecoverScreen = false;
            mTvRecoverScreen.setVisibility(HIDE);
        } else if (id == ResourceTable.Id_tv_settings) {
            new ToastDialog(getContext()).setText("click settings").show();
            _showAspectRatioOptions(true);
            mAspectRatioOptions.setVisibility(VISIBLE);
        } else if (id == ResourceTable.Id_tv_reload) {
            reload();
        }

    }

    /**==================== 屏幕翻转/切换处理 ====================*/

    /**
     * 使能视频翻转
     */
    public IjkPlayerView enableOrientation() {
        mIsForbidOrientation = false;
//        mOrientationListener.enable();
        return this;
    }

    /**
     * 全屏切换，点击全屏按钮
     */

    private void _toggleFullScreen() {
        if (WindowUtils.getScreenOrientation(mAttachActivity) == AbilityInfo.DisplayOrientation.LANDSCAPE) {
            //如果当前为横屏时，进行相应配置。
            mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
            mIvFullscreen.setPixelMap(ResourceTable.Media_ic_fullscreen);
            quiteNormalFullScreen();
            _exit();
            _toggleDanmakuView(false);
        } else {
            //如果当前为竖屏时，进行相应配置。
            _toggleDanmakuView(true);
            enterNormalFullScreen();
            mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
            mIvFullscreen.setPixelMap(ResourceTable.Media_ic_fullscreen_exit);
        }
    }

    /**
     * 全屏切换，点击全屏按钮
     */

    public void _setFullScreenView() {
        if (WindowUtils.getScreenOrientation(mAttachActivity) == AbilityInfo.DisplayOrientation.LANDSCAPE) {
            mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
            mIvFullscreen.setPixelMap(ResourceTable.Media_ic_fullscreen);
            quiteNormalFullScreen();
            _exit();
            _toggleDanmakuView(false);
        } else {
            _toggleDanmakuView(true);
            enterNormalFullScreen();
            mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
            mIvFullscreen.setPixelMap(ResourceTable.Media_ic_fullscreen_exit);
        }
    }

    /**
     * 设置全屏或窗口模式
     *
     * @param isFullScreen
     */
    private void _setFullScreen(boolean isFullScreen) {
        mIsFullscreen = isFullScreen;
//        // 处理弹幕相关视图
//        屏蔽弹幕功能
        _toggleDanmakuView(isFullScreen);
        _handleActionBar(isFullScreen);
        _changeHeight(isFullScreen);
        mIvFullscreen.setSelected(isFullScreen);
        mHandler.postTask(mHideBarRunnable);
        mIvMediaQuality.setVisibility(isFullScreen ? VISIBLE : HIDE);

        ShapeElement normalShapeElement = new ShapeElement();
        normalShapeElement.setRgbColor(RgbColor.fromRgbaInt(ResourceTable.Color_bg_video_view));

        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromRgbaInt(ResourceTable.Color_transparent));

        mLlBottomBar.setBackground(isFullScreen ? normalShapeElement : shapeElement);
        if (mIsShowQuality && !isFullScreen) {
            _toggleMediaQuality();
        }
        // 处理三指旋转缩放，如果之前进行了相关操作则全屏时还原之前旋转缩放的状态，窗口模式则将整个屏幕还原为未操作状态
        if (mIsNeedRecoverScreen) {
            if (isFullScreen) {
                mVideoView.adjustVideoView(1.0f);
                mTvRecoverScreen.setVisibility(mIsShowBar ? VISIBLE : HIDE);
            } else {
                mVideoView.resetVideoView(false);
                mTvRecoverScreen.setVisibility(HIDE);
            }
        }
        // 非全屏隐藏宽高比设置
        if (!isFullScreen) {
            _showAspectRatioOptions(false);
        }
    }

    private long tempLong;
    private boolean full_flag; //标记状态栏状态
    private boolean orientation_flag; //标记横竖屏状态
    //播放器当前状态
    int STATE_NORMAL = 0; //未播放
    int STATE_PREPARING = 1; //初始化中
    int STATE_PLAYING = 2; //播放中
    //去掉这个状态 缓冲只是显示个进度 不影响其他状态
    //int STATE_PLAYING_BUFFERING_START = 3; //缓冲
    int STATE_PAUSE = 4; //暂停中
    int STATE_AUTO_COMPLETE = 5; //播放完成
    int STATE_ERROR = 6; //播放出错

    //播放器容器模式
    int MODE_WINDOW_NORMAL = 100; //普通模式
    int MODE_WINDOW_FULLSCREEN = 101; //全屏模式
    int MODE_WINDOW_FLOAT_SYS = 102; //系统悬浮窗口模式 需要权限
    int MODE_WINDOW_FLOAT_ACT = 103; //界面内悬浮窗口模式

    protected int currentState = STATE_NORMAL;
    protected int currentMode = MODE_WINDOW_NORMAL;
    protected int seekToInAdvance; //初始化视频完成跳进度
    protected boolean noPlayInAdvance; //初始化视频完成 是否播放
    protected int aspectRatio;
    protected boolean isMute, openCache;
    protected float rate;

    /**
     * 进入全屏的模式 0横屏 1竖屏 2传感器自动横竖屏 3根据视频比例自动确定横竖屏      -1什么都不做
     */
    public int enterFullMode = 3;

    //防止频繁切换全屏
    private boolean checkSpaceOK() {
        long now = System.currentTimeMillis();
        long d = now - tempLong;
        if (d > 888) {
            tempLong = now;
        }
        return d > 888;
    }

    /**
     * 处理屏幕翻转
     *
     * @param orientation
     */
    private void _handleOrientation(int orientation) {
        if (mIsNeverPlay) {
            return;
        }
        if (mIsFullscreen && !mIsAlwaysFullScreen) {
            // 根据角度进行竖屏切换，如果为固定全屏则只能横屏切换
            if (orientation >= 0 && orientation <= 30 || orientation >= 330) {
                // 请求屏幕翻转
                mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.PORTRAIT);
            }
        } else {
            // 根据角度进行横屏切换
            if (orientation >= 60 && orientation <= 120) {
                mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
            } else if (orientation >= 240 && orientation <= 300) {
                mAttachActivity.setDisplayOrientation(AbilityInfo.DisplayOrientation.LANDSCAPE);
            }
        }
    }

    /**
     * 当屏幕执行翻转操作后调用禁止翻转功能，延迟3000ms再使能翻转，避免不必要的翻转
     */
    private void _refreshOrientationEnable() {
        if (!mIsForbidOrientation) {
//            mOrientationListener.disable();
            mHandler.removeEvent(MSG_ENABLE_ORIENTATION);
            mHandler.sendEvent(MSG_ENABLE_ORIENTATION, 3000);
        }
    }

    /**
     * 隐藏/显示 ActionBar
     *
     * @param isFullscreen
     */
    private void _handleActionBar(boolean isFullscreen) {
//        ActionBar supportActionBar = mAttachActivity.getSupportActionBar();
//        if (supportActionBar != null) {
//            if (isFullscreen) {
//                supportActionBar.hide();
//            } else {
//                supportActionBar.show();
//            }
//        }
    }

    /**
     * 改变视频布局高度
     *
     * @param isFullscreen
     */
    private void _changeHeight(boolean isFullscreen) {
        if (mIsAlwaysFullScreen) {
            return;
        }
        ComponentContainer.LayoutConfig layoutParams = getLayoutConfig();
        if (isFullscreen) {
            // 高度扩展为横向全屏
            layoutParams.height = mWidthPixels;
        } else {
            // 还原高度
            layoutParams.height = mInitHeight;
        }
        setLayoutConfig(layoutParams);
    }

    /**
     * 设置UI沉浸式显示
     */
    private void _setUiLayoutFullscreen() {
        mAttachActivity.getWindow().addFlags(WindowManager.LayoutConfig.MARK_FULL_SCREEN);
    }

    /**
     * 屏幕翻转后的处理，在 Activity.configurationChanged() 调用
     * SYSTEM_UI_FLAG_LAYOUT_STABLE：维持一个稳定的布局
     * SYSTEM_UI_FLAG_FULLSCREEN：Activity全屏显示，且状态栏被隐藏覆盖掉
     * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN：Activity全屏显示，但状态栏不会被隐藏覆盖，状态栏依然可见，Activity顶端布局部分会被状态遮住
     * SYSTEM_UI_FLAG_HIDE_NAVIGATION：隐藏虚拟按键(导航栏)
     * SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION：效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
     * SYSTEM_UI_FLAG_IMMERSIVE：沉浸式，从顶部下滑出现状态栏和导航栏会固定住
     * SYSTEM_UI_FLAG_IMMERSIVE_STICKY：黏性沉浸式，从顶部下滑出现状态栏和导航栏过几秒后会缩回去
     *
     * @param newConfig
     */
    public void configurationChanged(Configuration newConfig) {
//        _refreshOrientationEnable();
        if (newConfig.direction == Configuration.DIRECTION_HORIZONTAL) {
            //如果为横屏，设为全屏模式。
            _setFullScreen(true);
            mIvFullscreen.setPixelMap(ResourceTable.Media_ic_fullscreen_exit);
            mAttachActivity.getWindow().addFlags(WindowManager.LayoutConfig.MARK_FULL_SCREEN);
        } else if (newConfig.direction == Configuration.DIRECTION_VERTICAL) {
            //如果为竖屏，设为非全屏模式。
            _setFullScreen(false);
            mIvFullscreen.setPixelMap(ResourceTable.Media_ic_fullscreen);
            mAttachActivity.getWindow().clearFlags(WindowManager.LayoutConfig.MARK_FULL_SCREEN);
        }
    }

    /**
     * 从总显示全屏状态退出处理{@link #alwaysFullScreen()}
     */
    private void _exit() {
        if (System.currentTimeMillis() - mExitTime > 2000) {
            new ToastDialog(mAttachActivity.getContext()).setText("再按一次退出").show();
            mExitTime = System.currentTimeMillis();
        } else {
            mAttachActivity.terminateAbility();
        }
    }

    /**============================ 触屏操作处理 ============================*/

    /**
     * 隐藏视图Runnable
     */
    private Runnable mHideTouchViewRunnable = new Runnable() {
        @Override
        public void run() {
            _hideTouchView();
        }
    };

    /**
     * 触摸监听
     */
    private TouchEventListener mPlayerTouchListener = new TouchEventListener() {
        // 触摸模式：正常、无效、缩放旋转
        private static final int NORMAL = 1;
        private static final int INVALID_POINTER = 2;
        private static final int ZOOM_AND_ROTATE = 3;
        // 触摸模式
        private int mode = NORMAL;
        // 缩放的中点
        private Point midPoint = new Point(0, 0);
        // 旋转角度
        private float degree = 0;
        // 用来标识哪两个手指靠得最近，我的做法是取最近的两指中点和余下一指来控制旋转缩放
        private int fingerFlag = INVALID_VALUE;
        // 初始间距
        private float oldDist;
        // 缩放比例
        private float scale;

        @Override
        public boolean onTouchEvent(Component v, TouchEvent event) {
            LogUtil.error("IjkPlayerView.mHandler", "onTouchEvent event.getAction(): "
                    + event.getAction());
            LogUtil.error("IjkPlayerView.mHandler", "onTouchEvent event.getIndex(): "
                    + event.getIndex());
            LogUtil.error("IjkPlayerView.mHandler", "getMultimodalEvent: "
                    + event.getMultimodalEvent());
            switch (event.getAction()) {
                case TouchEvent.OTHER_POINT_DOWN:
                    mode = NORMAL;
                    mHandler.removeTask(mHideBarRunnable);
                    break;

                case TouchEvent.PRIMARY_POINT_DOWN:
                    if (event.getPointerCount() == 3 && mIsFullscreen) {
                        _hideTouchView();
                        // 进入三指旋转缩放模式，进行相关初始化
                        mode = ZOOM_AND_ROTATE;
                        MotionEventUtils.midPoint(midPoint, event);
                        fingerFlag = MotionEventUtils.calcFingerFlag(event);
                        degree = MotionEventUtils.rotation(event, fingerFlag);
                        oldDist = MotionEventUtils.calcSpacing(event, fingerFlag);
                        // 获取视频的 Matrix
                        mSaveMatrix = mVideoView.getVideoTransform();
                    } else {
                        mode = INVALID_POINTER;
                    }
                    break;

                case TouchEvent.POINT_MOVE:
                    if (mode == ZOOM_AND_ROTATE) {
                        // 处理旋转
                        float newRotate = MotionEventUtils.rotation(event, fingerFlag);
                        mVideoView.setVideoRotation((int) (newRotate - degree));
                        // 处理缩放
                        mVideoMatrix.setMatrix(mSaveMatrix);
                        float newDist = MotionEventUtils.calcSpacing(event, fingerFlag);
                        scale = newDist / oldDist;
                        mVideoMatrix.postScale(scale
                                , scale, midPoint.getPointX(), midPoint.getPointY());
                        mVideoView.setVideoTransform(mVideoMatrix);
                    }
                    break;

                case TouchEvent.PRIMARY_POINT_UP:
                    if (mode == ZOOM_AND_ROTATE) {
                        // 调整视频界面，让界面居中显示在屏幕
                        mIsNeedRecoverScreen = mVideoView.adjustVideoView(scale);
                        if (mIsNeedRecoverScreen && mIsShowBar) {
                            mTvRecoverScreen.setVisibility(VISIBLE);
                        }
                    }
                    mode = INVALID_POINTER;
                    break;
            }
            // 触屏手势处理
            if (mode == NORMAL) {
//                if (mGestureDetector.onTouchEvent(mVideoView, event)) {
//                    return true;
//                }
                if (event.getAction() == TouchEvent.PRIMARY_POINT_UP) {
                    _endGesture();
                }
            }
            return true;
        }
    };

    public void destroy() {
        release();
    }


    /**
     * 更新进度条
     *
     * @return
     */
    private int _setProgress() {
        LogUtil.error("IjkPlayerView.mHandler", "mVideoView: " + mVideoView);
        LogUtil.error("IjkPlayerView.mHandler", "mIsSeeking: " + mIsSeeking);
        if (mVideoView == null || mIsSeeking) {
            return 0;
        }

        LogUtil.error("IjkPlayerView.mHandler", "视频播放的当前进度: " + mVideoView.getCurrentPosition());
        // 视频播放的当前进度
        int position = Math.max(mVideoView.getCurrentPosition(), mInterruptPosition);
        // 视频总的时长
        LogUtil.error("IjkPlayerView.mHandler", "视频总的时长: " + mVideoView.getDuration());
        int duration = (int) mVideoView.getDuration();
        if (duration > 0) {
            // 转换为 Seek 显示的进度值
            long pos = (long) MAX_VIDEO_SEEK * position / duration;
            mPlayerSeek.setProgressValue((int) pos);
//            屏蔽弹幕功能
            if (mIsEnableDanmaku) {
                mDanmakuPlayerSeek.setProgressValue((int) pos);
            }
        }
        // 获取缓冲的进度百分比，并显示在 Seek 的次进度
        int percent = mVideoView.getBufferPercentage();
        mPlayerSeek.setViceProgress(percent * 10);
//        屏蔽弹幕功能
        if (mIsEnableDanmaku) {
            mDanmakuPlayerSeek.setViceProgress(percent * 10);
        }
        // 更新播放时间
        mTvCurTime.setText(generateTime(position));
        mTvEndTime.setText(generateTime(duration));
        // 返回当前播放进度
        return position;
    }

    /**
     * 设置快进
     *
     * @param time
     */
    private void _setFastForward(String time) {
        if (mFlTouchLayout.getVisibility() == HIDE) {
            mFlTouchLayout.setVisibility(VISIBLE);
        }
        if (mTvFastForward.getVisibility() == HIDE) {
            mTvFastForward.setVisibility(VISIBLE);
            mTvBrightness.setVisibility(HIDE);
            mTvVolume.setVisibility(HIDE);
            mTvFastRewind.setVisibility(HIDE);
        }
        mTvFastForward.setText(time);
    }

    /**
     * 设置快退
     *
     * @param time
     */
    private void _setFastRewind(String time) {
        if (mFlTouchLayout.getVisibility() == HIDE) {
            mFlTouchLayout.setVisibility(VISIBLE);
        }
        if (mTvFastRewind.getVisibility() == HIDE) {
            mTvFastRewind.setVisibility(VISIBLE);
            mTvBrightness.setVisibility(HIDE);
            mTvVolume.setVisibility(HIDE);
            mTvFastForward.setVisibility(HIDE);
        }
        mTvFastRewind.setText(time);
    }

    /**
     * 隐藏触摸视图
     */
    private void _hideTouchView() {
        LogUtil.info("IjkPlayerView._hideTouchView", "_hideTouchView ");
        if (mFlTouchLayout.getVisibility() == VISIBLE) {
            mTvFastForward.setVisibility(HIDE);
            mTvVolume.setVisibility(HIDE);
            mTvBrightness.setVisibility(HIDE);
            mFlTouchLayout.setVisibility(HIDE);
        }
    }

    /**
     * 快进或者快退滑动改变进度，这里处理触摸滑动不是拉动 SeekBar
     *
     * @param delta 拖动的时间
     */
    private void _onProgressSlide(int delta) {
        int position = mVideoView.getCurrentPosition();
        long duration = mVideoView.getDuration();
//        // 单次拖拽最大时间差为100秒或播放时长的1/2
//        long deltaMax = Math.min(100 * 1000, duration / 2);
//        // 计算滑动时间
//        long delta = (long) (deltaMax * percent);
        // 目标位置
        mTargetPosition = delta + position;
        if (mTargetPosition > duration) {
            mTargetPosition = duration;
        } else if (mTargetPosition <= 0) {
            mTargetPosition = 0;
        }
        int deltaTime = (int) ((mTargetPosition - position) / 1000);
        String desc;
        // 对比当前位置来显示快进或后退
        if (mTargetPosition > position) {
            desc = generateTime(mTargetPosition) + "/"
                    + generateTime(duration) + "\n" + "+" + deltaTime + "秒";
            _setFastForward(desc);
        } else {
            desc = generateTime(mTargetPosition) + "/"
                    + generateTime(duration) + "\n" + deltaTime + "秒";
            _setFastRewind(desc);
        }
    }

    /**
     * 设置声音控制显示
     *
     * @param volume
     */
    private void _setVolumeInfo(int volume) {
        if (mFlTouchLayout.getVisibility() == HIDE) {
            mFlTouchLayout.setVisibility(VISIBLE);
        }
        if (mTvVolume.getVisibility() == HIDE) {
            mTvVolume.setVisibility(VISIBLE);
            mTvFastForward.setVisibility(HIDE);
            mTvFastRewind.setVisibility(HIDE);
            mTvBrightness.setVisibility(HIDE);
        }
        mTvVolume.setText((volume * 100 / mMaxVolume) + "%");
    }

    /**
     * 滑动改变声音大小
     *
     * @param percent
     */
    private void _onVolumeSlide(float percent) {
        if (mCurVolume == INVALID_VALUE) {
            try {
                mCurVolume = mAudioManager.getVolume(AudioManager.AudioVolumeType.STREAM_MUSIC);
            } catch (AudioRemoteException e) {
                e.printStackTrace();
            }
            if (mCurVolume < 0) {
                mCurVolume = 0;
            }
        }
        int nowVolume = (int) (percent * mMaxVolume) + mCurVolume;
        if (nowVolume > mMaxVolume) {
            nowVolume = mMaxVolume;
        }
        if (nowVolume < 0) {
            nowVolume = 0;
        }
        // 变更声音
        mAudioManager.setVolume(AudioManager.AudioVolumeType.STREAM_MUSIC, nowVolume);
        // 变更进度条
        _setVolumeInfo(nowVolume);
    }


    /**
     * 递增或递减音量，量度按最大音量的 1/15
     *
     * @param isIncrease 递增或递减
     */
    private void _setVolume(boolean isIncrease) {
        int curVolume = 0;
        try {
            curVolume = mAudioManager.getVolume(AudioManager.AudioVolumeType.STREAM_MUSIC);
        } catch (AudioRemoteException e) {
            e.printStackTrace();
        }
        if (isIncrease) {
            curVolume += mMaxVolume / 15;
        } else {
            curVolume -= mMaxVolume / 15;
        }
        if (curVolume > mMaxVolume) {
            curVolume = mMaxVolume;
        } else if (curVolume < 0) {
            curVolume = 0;
        }
        // 变更声音
        mAudioManager.setVolume(AudioManager.AudioVolumeType.STREAM_MUSIC, curVolume);
        // 变更进度条
        _setVolumeInfo(curVolume);
        mHandler.removeTask(mHideTouchViewRunnable);
        mHandler.postTask(mHideTouchViewRunnable, 1000);
    }

    /**
     * 设置亮度控制显示
     *
     * @param brightness
     */
    private void _setBrightnessInfo(float brightness) {
        if (mFlTouchLayout.getVisibility() == HIDE) {
            mFlTouchLayout.setVisibility(VISIBLE);
        }
        if (mTvBrightness.getVisibility() == HIDE) {
            mTvBrightness.setVisibility(VISIBLE);
            mTvFastForward.setVisibility(HIDE);
            mTvVolume.setVisibility(HIDE);
            mTvFastRewind.setVisibility(HIDE);
        }
        mTvBrightness.setText(Math.ceil(brightness * 100) + "%");
    }

    /**
     * 滑动改变亮度大小
     *
     * @param percent
     */
    private void _onBrightnessSlide(float percent) {
        if (mCurBrightness < 0) {
            mCurBrightness = mAttachActivity.getWindow().getLayoutConfig().get().windowBrightness;
            if (mCurBrightness < 0.0f) {
                mCurBrightness = 0.5f;
            } else if (mCurBrightness < 0.01f) {
                mCurBrightness = 0.01f;
            }
        }

        WindowManager.LayoutConfig attributes = mAttachActivity.getWindow().getLayoutConfig().get();
        attributes.windowBrightness = mCurBrightness + percent;
        if (attributes.windowBrightness > 1.0f) {
            attributes.windowBrightness = 1.0f;
        } else if (attributes.windowBrightness < 0.01f) {
            attributes.windowBrightness = 0.01f;
        }
        _setBrightnessInfo(attributes.windowBrightness);
        mAttachActivity.getWindow().setLayoutConfig(attributes);
    }

    /**
     * 手势结束调用
     */
    private void _endGesture() {
        if (mTargetPosition >= 0 && mTargetPosition != mVideoView.getCurrentPosition()) {
            // 更新视频播放进度
            seekTo((int) mTargetPosition);
            mPlayerSeek.setProgressValue((int) (mTargetPosition
                    * MAX_VIDEO_SEEK / mVideoView.getDuration()));
//            屏蔽弹幕功能
            if (mIsEnableDanmaku) {
                mDanmakuPlayerSeek.setProgressValue((int) (mTargetPosition
                        * MAX_VIDEO_SEEK / mVideoView.getDuration()));
            }
            mTargetPosition = INVALID_VALUE;
        }
        // 隐藏触摸操作显示图像
        _hideTouchView();
        _refreshHideRunnable();
        mCurVolume = INVALID_VALUE;
        mCurBrightness = INVALID_VALUE;
    }

    /**
     * ============================ 播放状态控制 ============================
     */

    // 这个用来控制弹幕启动和视频同步
    private boolean mIsRenderingStart = false;
    // 缓冲开始，这个用来控制弹幕启动和视频同步
    private boolean mIsBufferingStart = false;

    // 视频播放状态监听
    private OnInfoListener mInfoListener = new OnInfoListener() {
        @Override
        public boolean onInfo(IMediaPlayer iMediaPlayer, int status, int extra) {
            _switchStatus(status);
            if (mOutsideInfoListener != null) {
                mOutsideInfoListener.onInfo(iMediaPlayer, status, extra);
            }
            return true;
        }
    };

    /**
     * 视频播放状态处理
     *
     * @param status
     */
    private void _switchStatus(int status) {
        LogUtil.info("IjkPlayerView", "status " + status);
        switch (status) {
            case IMediaPlayer.MEDIA_INFO_BUFFERING_START:
                mIsBufferingStart = true;
//                屏蔽弹幕功能
//                _pauseDanmaku();
                if (!mIsNeverPlay) {
                    mLoadingView.setVisibility(VISIBLE);
                }
                mHandler.removeEvent(MSG_TRY_RELOAD);
            case MediaPlayerParams.STATE_PREPARING:
                break;

            case MediaPlayerParams.STATE_PREPARED:
                mIsReady = true;
                break;

            case IMediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START:
                mIsRenderingStart = true;
            case IMediaPlayer.MEDIA_INFO_BUFFERING_END:
                mIsBufferingStart = false;
                mLoadingView.setVisibility(HIDE);
                mPlayerThumb.setVisibility(HIDE);
                // 更新进度
                mHandler.removeEvent(MSG_UPDATE_SEEK);
                mHandler.sendEvent(MSG_UPDATE_SEEK);
                if (mSkipPosition != INVALID_VALUE) {
                    _showSkipTip(); // 显示跳转提示
                }
                if (mVideoView.isPlaying() && mIsNetConnected) {
                    mInterruptPosition = 0;
//                    屏蔽弹幕功能
//                    _resumeDanmaku();   // 开启弹幕
                    if (!mIvPlay.isSelected()) {
                        // 这里处理断网重连后不会播放情况
                        mVideoView.start();
                        mIvPlay.setSelected(true);
                        mDanmakuView.resume();
                        mIvPlay.setPixelMap(ResourceTable.Media_ic_video_pause);
                    }
                }
                break;

            case MediaPlayerParams.STATE_PLAYING:
                mHandler.removeEvent(MSG_TRY_RELOAD);
                if (mIsRenderingStart && !mIsBufferingStart
                        && mVideoView.getCurrentPosition() > 0) {
//                    屏蔽弹幕功能
//                    _resumeDanmaku();   // 开启弹幕
                }
                break;
            case MediaPlayerParams.STATE_ERROR:
                mInterruptPosition = Math.max(mVideoView.getInterruptPosition(), mInterruptPosition);
                pause();
                if (mVideoView.getDuration() == -1 && !mIsReady) {
                    mLoadingView.setVisibility(HIDE);
                    mPlayerThumb.setVisibility(HIDE);
                    mIvPlayCircle.setVisibility(HIDE);
                    mFlReload.setVisibility(VISIBLE);
                } else {
                    mLoadingView.setVisibility(VISIBLE);
                    mHandler.sendEvent(MSG_TRY_RELOAD);
                }
                break;

            case MediaPlayerParams.STATE_COMPLETED:
                pause();
                if (mVideoView.getDuration() == -1
                        || (mVideoView.getInterruptPosition()
                        + INTERVAL_TIME < mVideoView.getDuration())) {
                    mInterruptPosition
                            = Math.max(mVideoView.getInterruptPosition(), mInterruptPosition);
                    new ToastDialog(mAttachActivity.getContext()).setText("网络异常").show();
                } else {
                    mIsPlayComplete = true;
                    if (mCompletionListener != null) {
                        mCompletionListener.onCompletion(mVideoView.getMediaPlayer());
                    }
                }
                break;
        }
    }

    /**============================ Listener ============================*/

    /**
     * Register a callback to be invoked when the media file
     * is loaded and ready to go.
     *
     * @param l The callback that will be run
     */
    public void setOnPreparedListener(IMediaPlayer.OnPreparedListener l) {
        mVideoView.setOnPreparedListener(l);
    }

    /**
     * Register a callback to be invoked when the end of a media file
     * has been reached during playback.
     *
     * @param l The callback that will be run
     */
    public void setOnCompletionListener(IMediaPlayer.OnCompletionListener l) {
        mCompletionListener = l;
//        mVideoView.setOnCompletionListener(l);
    }

    /**
     * Register a callback to be invoked when an error occurs
     * during playback or setup.  If no listener is specified,
     * or if the listener returned false, VideoView will inform
     * the user of any errors.
     *
     * @param l The callback that will be run
     */
    public void setOnErrorListener(IMediaPlayer.OnErrorListener l) {
        mVideoView.setOnErrorListener(l);
    }

    /**
     * Register a callback to be invoked when an informational event
     * occurs during playback or setup.
     *
     * @param l The callback that will be run
     */
    public void setOnInfoListener(OnInfoListener l) {
        mOutsideInfoListener = l;
    }

    /**
     * 设置弹幕监听器
     *
     * @param danmakuListener
     */
    public IjkPlayerView setDanmakuListener(OnDanmakuListener danmakuListener) {
//        屏蔽弹幕功能
//        mDanmakuListener = danmakuListener;
        return this;
    }

    /**
     * ============================ 播放清晰度 ============================
     */

    // 默认显示/隐藏选择分辨率界面时间
    private static final int DEFAULT_QUALITY_TIME = 300;
    /**
     * 依次分别为：流畅、清晰、高清、超清和1080P
     */
    public static final int MEDIA_QUALITY_SMOOTH = 0;
    public static final int MEDIA_QUALITY_MEDIUM = 1;
    public static final int MEDIA_QUALITY_HIGH = 2;
    public static final int MEDIA_QUALITY_SUPER = 3;
    public static final int MEDIA_QUALITY_BD = 4;

    private static final int QUALITY_DRAWABLE_RES[] = new int[]{
            ResourceTable.Media_ic_media_quality_smooth,
            ResourceTable.Media_ic_media_quality_medium,
            ResourceTable.Media_ic_media_quality_high,
            ResourceTable.Media_ic_media_quality_super,
            ResourceTable.Media_ic_media_quality_bd
    };
    // 保存Video Url
    private PlainArray<String> mVideoSource = new PlainArray<>();
    // 描述信息
    private String[] mMediaQualityDesc;
    // 分辨率选择布局
    private Component mFlMediaQuality;
    // 清晰度
    private Text mIvMediaQuality;
    // 分辨率选择列表
    private ListContainer mLvMediaQuality;
    // 分辨率选择列表适配器
    private AdapterMediaQuality mQualityAdapter;
    // 列表数据
    private List<MediaQualityInfo> mQualityData;
    // 是否显示分辨率选择列表
    private boolean mIsShowQuality = true;
    // 当前选中的分辨率
    private
    @MediaQuality
    int mCurSelectQuality = MEDIA_QUALITY_SMOOTH;

    @Retention(RetentionPolicy.SOURCE)
    @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
    @IntDef({MEDIA_QUALITY_SMOOTH, MEDIA_QUALITY_MEDIUM,
            MEDIA_QUALITY_HIGH, MEDIA_QUALITY_SUPER, MEDIA_QUALITY_BD})
    public @interface MediaQuality {
    }

    /**
     * 初始化视频分辨率处理
     */
    private void _initMediaQuality() {
        Element elementStrarray;
        try {
            elementStrarray = getResourceManager().getElement(ResourceTable.Strarray_media_quality);
            mMediaQualityDesc = elementStrarray.getStringArray();
            mFlMediaQuality = findComponentById(ResourceTable.Id_fl_media_quality);
            mIvMediaQuality = (Text) findComponentById(ResourceTable.Id_iv_media_quality);
            mIvMediaQuality.setClickedListener(this);
            mLvMediaQuality = (ListContainer) findComponentById(ResourceTable.Id_lv_media_quality);
            mQualityAdapter = new AdapterMediaQuality(mAttachActivity);
            mLvMediaQuality.setItemProvider(mQualityAdapter);

            mLvMediaQuality.setItemClickedListener(new ListContainer.ItemClickedListener() {
                @Override
                public void onItemClicked(ListContainer listContainer
                        , Component component, int position, long id) {
                    if (mCurSelectQuality != mQualityAdapter.getItem(position).getIndex()) {
                        setMediaQuality(mQualityAdapter.getItem(position).getIndex());
                        mLoadingView.setVisibility(VISIBLE);
                        start();
                    }
                    _toggleMediaQuality();
                }
            });
        } catch (IOException | NotExistException | WrongTypeException e) {
            e.printStackTrace();
        }

    }


    /**
     * 切换视频
     *
     * @param mediaSmooth 流畅
     * @param mediaMedium 清晰
     * @param mediaHigh   高清
     * @param mediaSuper  超清
     * @param mediaBd     1080P
     * @return
     */
    public IjkPlayerView switchVideoSource(String mediaSmooth
            , String mediaMedium, String mediaHigh, String mediaSuper, String mediaBd) {
        reset();
        return setVideoSource(mediaSmooth, mediaMedium, mediaHigh, mediaSuper, mediaBd);
    }

    /**
     * 设置视频源
     *
     * @param mediaSmooth 流畅
     * @param mediaMedium 清晰
     * @param mediaHigh   高清
     * @param mediaSuper  超清
     * @param mediaBd     1080P
     */
    public IjkPlayerView setVideoSource(String mediaSmooth
            , String mediaMedium, String mediaHigh, String mediaSuper, String mediaBd) {
        boolean isSelect = true;
        mQualityData = new ArrayList<>();
        if (mediaSmooth != null) {
            mVideoSource.put(MEDIA_QUALITY_SMOOTH, mediaSmooth);
            mQualityData.add(new MediaQualityInfo(MEDIA_QUALITY_SMOOTH
                    , mMediaQualityDesc[MEDIA_QUALITY_SMOOTH], isSelect));
            mCurSelectQuality = MEDIA_QUALITY_SMOOTH;
            isSelect = false;
        }
        if (mediaMedium != null) {
            mVideoSource.put(MEDIA_QUALITY_MEDIUM, mediaMedium);
            mQualityData.add(new MediaQualityInfo(MEDIA_QUALITY_MEDIUM
                    , mMediaQualityDesc[MEDIA_QUALITY_MEDIUM], isSelect));
            if (isSelect) {
                mCurSelectQuality = MEDIA_QUALITY_MEDIUM;
            }
            isSelect = false;
        }
        if (mediaHigh != null) {
            mVideoSource.put(MEDIA_QUALITY_HIGH, mediaHigh);
            mQualityData.add(new MediaQualityInfo(MEDIA_QUALITY_HIGH
                    , mMediaQualityDesc[MEDIA_QUALITY_HIGH], isSelect));
            if (isSelect) {
                mCurSelectQuality = MEDIA_QUALITY_HIGH;
            }
            isSelect = false;
        }
        if (mediaSuper != null) {
            mVideoSource.put(MEDIA_QUALITY_SUPER, mediaSuper);
            mQualityData.add(new MediaQualityInfo(MEDIA_QUALITY_SUPER
                    , mMediaQualityDesc[MEDIA_QUALITY_SUPER], isSelect));
            if (isSelect) {
                mCurSelectQuality = MEDIA_QUALITY_SUPER;
            }
            isSelect = false;
        }
        if (mediaBd != null) {
            mVideoSource.put(MEDIA_QUALITY_BD, mediaBd);
            mQualityData.add(new MediaQualityInfo(MEDIA_QUALITY_BD
                    , mMediaQualityDesc[MEDIA_QUALITY_BD], isSelect));
            if (isSelect) {
                mCurSelectQuality = MEDIA_QUALITY_BD;
            }
        }
        mQualityAdapter.updateItems(mQualityData);
        try {
            Resource resource
                    = getResourceManager().getResource(QUALITY_DRAWABLE_RES[mCurSelectQuality]);
            PixelMapElement element = new PixelMapElement(resource);
            mIvMediaQuality.setAroundElements(null, element, null, null);
            mIvMediaQuality.setText(mMediaQualityDesc[mCurSelectQuality]);
            LogUtil.error("IjkPlayerView.setVideoSource", "setVideoPath: "
                    + mVideoSource.get(mCurSelectQuality));
            setVideoPath(mVideoSource.get(mCurSelectQuality).get());
        } catch (IOException | NotExistException e) {
            e.printStackTrace();
        }

        return this;
    }

    /**
     * 选择视频源
     *
     * @param quality 分辨率
     *                {@link #MEDIA_QUALITY_SMOOTH,#MEDIA_QUALITY_MEDIUM,#MEDIA_QUALITY_HIGH,#MEDIA_QUALITY_SUPER,#MEDIA_QUALITY_BD}
     * @return
     */
    public IjkPlayerView setMediaQuality(@MediaQuality int quality) {
        if (mCurSelectQuality == quality || mVideoSource.get(quality) == null) {
            return this;
        }
        mQualityAdapter.setMediaQuality(quality);
        try {
            Resource resource = getResourceManager().getResource(QUALITY_DRAWABLE_RES[quality]);
            PixelMapElement element = new PixelMapElement(resource);
            mIvMediaQuality.setAroundElements(null, element, null, null);
            mIvMediaQuality.setText(mMediaQualityDesc[quality]);
            mCurSelectQuality = quality;
            if (mVideoView.isPlaying()) {
                mCurPosition = mVideoView.getCurrentPosition();
                mVideoView.release(false);
            }
            mVideoView.setRender(IjkVideoView.RENDER_TEXTURE_VIEW);
            setVideoPath(mVideoSource.get(quality).get());
        } catch (IOException | NotExistException e) {
            e.printStackTrace();
        }
        return this;
    }

    /**
     * ============================ 跳转提示 ============================
     */

    // 取消跳转
    private Image mIvCancelSkip;
    // 跳转时间
    private Text mTvSkipTime;
    // 执行跳转
    private Text mTvDoSkip;
    // 跳转布局
    private Component mLlSkipLayout;
    // 跳转目标时间
    private int mSkipPosition = INVALID_VALUE;

    /**
     * 跳转提示初始化
     */
    private void _initVideoSkip() {
        mLlSkipLayout = findComponentById(ResourceTable.Id_ll_skip_layout);
        mIvCancelSkip = (Image) findComponentById(ResourceTable.Id_iv_cancel_skip);
        mTvSkipTime = (Text) findComponentById(ResourceTable.Id_tv_skip_time);
        mTvDoSkip = (Text) findComponentById(ResourceTable.Id_tv_do_skip);
        mIvCancelSkip.setClickedListener(this);
        mTvDoSkip.setClickedListener(this);
    }

    /**
     * 返回当前进度
     *
     * @return
     */
    public int getCurPosition() {
        return mVideoView.getCurrentPosition();
    }

    /**
     * 设置跳转提示
     *
     * @param targetPosition 目标进度,单位:ms
     */
    public IjkPlayerView setSkipTip(int targetPosition) {
        mSkipPosition = targetPosition;
        return this;
    }

    /**
     * 显示跳转提示
     */
    private void _showSkipTip() {
        if (mSkipPosition != INVALID_VALUE && mLlSkipLayout.getVisibility() == HIDE) {
            mLlSkipLayout.setVisibility(VISIBLE);
            mTvSkipTime.setText(generateTime(mSkipPosition));
            AnimHelper.doSlideRightIn(mLlSkipLayout, mWidthPixels, 0, 800);
            mHandler.postTask(mHideSkipTipRunnable, DEFAULT_HIDE_TIMEOUT * 3);
        }
    }

    /**
     * 隐藏跳转提示
     */
    private void _hideSkipTip() {
        if (mLlSkipLayout.getVisibility() == HIDE) {
            return;
        }
        mLlSkipLayout.createAnimatorProperty()
                .moveFromX(-mLlSkipLayout.getWidth())
                .alpha(0).setDuration(500)
                .setStateChangedListener(new Animator.StateChangedListener() {
                    @Override
                    public void onStart(Animator animator) {

                    }

                    @Override
                    public void onStop(Animator animator) {

                    }

                    @Override
                    public void onCancel(Animator animator) {

                    }

                    @Override
                    public void onEnd(Animator animator) {
                        mLlSkipLayout.setVisibility(HIDE);
                    }

                    @Override
                    public void onPause(Animator animator) {

                    }

                    @Override
                    public void onResume(Animator animator) {

                    }
                }).start();
        mSkipPosition = INVALID_VALUE;
    }

    /**
     * 隐藏跳转提示线程
     */
    private Runnable mHideSkipTipRunnable = new Runnable() {
        @Override
        public void run() {
            _hideSkipTip();
        }
    };

    /**
     * ============================ 弹幕 ============================
     */

    /**
     * 视频编辑状态：正常未编辑状态、在播放时编辑、暂停时编辑
     */
    private static final int NORMAL_STATUS = 501;
    private static final int INTERRUPT_WHEN_PLAY = 502;
    private static final int INTERRUPT_WHEN_PAUSE = 503;

    private int mVideoStatus = NORMAL_STATUS;

    // 弹幕格式：B站、A站和自定义
    private static final int DANMAKU_TAG_BILI = 701;
    private static final int DANMAKU_TAG_ACFUN = 702;
    private static final int DANMAKU_TAG_CUSTOM = 703;

    @Retention(RetentionPolicy.SOURCE)
    @Target({ElementType.FIELD, ElementType.PARAMETER})
    @IntDef({DANMAKU_TAG_BILI, DANMAKU_TAG_ACFUN, DANMAKU_TAG_CUSTOM})
    public @interface DanmakuTag {
    }

    private
    @DanmakuTag
    int mDanmakuTag = DANMAKU_TAG_BILI;
//
//    // 弹幕开源控件
//    private IDanmakuView mDanmakuView;
//    // 弹幕显示/隐藏按钮
//    private Image mIvDanmakuControl;
//    // 弹幕编辑布局打开按钮
//    private Text mTvOpenEditDanmaku;
//    // 使能弹幕才会显示的播放进度条
//    private Slider mDanmakuPlayerSeek;
//    // 使能弹幕才会显示时间分割线
//    private Text mTvTimeSeparator;
//    // 弹幕编辑布局
//    private Component mEditDanmakuLayout;
//    // 弹幕内容编辑框
//    private TextField mEtDanmakuContent;
//    // 取消弹幕发送
//    private Image mIvCancelSend;
//    // 发送弹幕
//    private Image mIvDoSend;
//
//    // 弹幕基础设置布局
//    private Component mDanmakuOptionsBasic;
//    // 弹幕字体大小选项卡
//    private RadioContainer mDanmakuTextSizeOptions;
//    // 弹幕类型选项卡
//    private RadioContainer mDanmakuTypeOptions;
//    // 弹幕当前颜色
//    private RadioButton mDanmakuCurColor;
//    // 开关弹幕颜色选项卡
//    private Image mDanmakuMoreColorIcon;
//    // 弹幕更多颜色设置布局
//    private Component mDanmakuMoreOptions;
//    // 弹幕颜色选项卡
//    private RadioContainer mDanmakuColorOptions;
//
//    // 弹幕控制相关
//    private DanmakuContext mDanmakuContext;
//    // 弹幕解析器
//    private BaseDanmakuParser mDanmakuParser;
//    // 弹幕加载器
//    private ILoader mDanmakuLoader;
//    // 弹幕数据转换器
//    private BaseDanmakuConverter mDanmakuConverter;
//    // 弹幕监听器
//    private OnDanmakuListener mDanmakuListener;
//    // 是否使能弹幕
//    private boolean mIsEnableDanmaku = false;
//    // 弹幕颜色
//    private int mDanmakuTextColor = Color.WHITE.getValue();
//    // 弹幕字体大小
//    private float mDanmakuTextSize = INVALID_VALUE;
//    // 弹幕类型
//    private int mDanmakuType = BaseDanmaku.TYPE_SCROLL_RL;
//    // 弹幕基础设置布局的宽度
//    private int mBasicOptionsWidth = INVALID_VALUE;
//    // 弹幕更多颜色设置布局宽度
//    private int mMoreOptionsWidth = INVALID_VALUE;
//    // 弹幕要跳转的目标位置，等视频播放再跳转，不然老出现只有弹幕在动的情况
//    private long mDanmakuTargetPosition = INVALID_VALUE;

    /**
     * 弹幕初始化
     */
//    屏蔽弹幕功能
//    private void _initDanmaku() {
//        // 弹幕控制
//        mDanmakuView = (IDanmakuView) findComponentById(ResourceTable.Id_sv_danmaku);
//        mIvDanmakuControl = (Image) findComponentById(ResourceTable.Id_iv_danmaku_control);
//        mTvOpenEditDanmaku = (Text) findComponentById(ResourceTable.Id_tv_open_edit_danmaku);
//        mTvTimeSeparator = (Text) findComponentById(ResourceTable.Id_tv_separator);
//        mEditDanmakuLayout = findComponentById(ResourceTable.Id_ll_edit_danmaku);
//        mEtDanmakuContent = (TextField) findComponentById(ResourceTable.Id_et_danmaku_content);
//        mIvCancelSend = (Image) findComponentById(ResourceTable.Id_iv_cancel_send);
//        mIvDoSend = (Image) findComponentById(ResourceTable.Id_iv_do_send);
//        mDanmakuPlayerSeek = (Slider) findComponentById(ResourceTable.Id_danmaku_player_seek);
//        mDanmakuPlayerSeek.setMaxValue(MAX_VIDEO_SEEK);
//        mDanmakuPlayerSeek.setValueChangedListener(mSeekListener);
//
//        int navigationBarHeight = NavUtils.getNavigationBarHeight(mAttachActivity);
//        if (navigationBarHeight > 0) {
//            // 对于有虚拟键的设备需要将弹幕编辑布局右偏移防止被覆盖
//            mEditDanmakuLayout.setPadding(0, 0, navigationBarHeight, 0);
//        }
//
//        mIvDanmakuControl.setClickedListener(this);
//        mTvOpenEditDanmaku.setClickedListener(this);
//        mIvCancelSend.setClickedListener(this);
//        mIvDoSend.setClickedListener(this);
//
//        // 这些为弹幕配置处理
//        int oneBtnWidth = 0;
//        try {
//            oneBtnWidth = getResourceManager().getElement(42).getInteger();
//        } catch (IOException | NotExistException | WrongTypeException e) {
//            e.printStackTrace();
//        }
//        // 布局宽度为每个选项卡宽度 * 12 个，有12种可选颜色
//        mMoreOptionsWidth = oneBtnWidth * 12;
//        mDanmakuOptionsBasic = findComponentById(ResourceTable.Id_input_options_basic);
//        mDanmakuMoreOptions = findComponentById(ResourceTable.Id_input_options_more);
//        mDanmakuMoreOptions.setClickedListener(this);
//        mDanmakuCurColor = (RadioButton) findComponentById(ResourceTable.Id_input_options_color_current);
//        mDanmakuMoreColorIcon = (Image) findComponentById(ResourceTable.Id_input_options_color_more_icon);
//        mDanmakuTextSizeOptions = (RadioContainer) findComponentById(ResourceTable.Id_input_options_group_textsize);
//        mDanmakuTypeOptions = (RadioContainer) findComponentById(ResourceTable.Id_input_options_group_type);
//        mDanmakuColorOptions = (RadioContainer) findComponentById(ResourceTable.Id_input_options_color_group);
//
//        mDanmakuTextSizeOptions.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
//            @Override
//            public void onCheckedChanged(RadioContainer radioContainer, int checkedId) {
//                if (checkedId == ResourceTable.Id_input_options_small_textsize) {
//                    mDanmakuTextSize = 25f * (mDanmakuParser.getDisplayer().getDensity() - 0.6f) * 0.7f;
//                } else if (checkedId == ResourceTable.Id_input_options_medium_textsize) {
//                    mDanmakuTextSize = 25f * (mDanmakuParser.getDisplayer().getDensity() - 0.6f);
//                }
//            }
//        });
//
//        mDanmakuTypeOptions.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
//            @Override
//            public void onCheckedChanged(RadioContainer group, int checkedId) {
//                if (checkedId == ResourceTable.Id_input_options_rl_type) {
//                    mDanmakuType = BaseDanmaku.TYPE_SCROLL_RL;
//                } else if (checkedId == ResourceTable.Id_input_options_top_type) {
//                    mDanmakuType = BaseDanmaku.TYPE_FIX_TOP;
//                } else if (checkedId == ResourceTable.Id_input_options_bottom_type) {
//                    mDanmakuType = BaseDanmaku.TYPE_FIX_BOTTOM;
//                }
//            }
//        });
//
//        mDanmakuColorOptions.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() {
//            @Override
//            public void onCheckedChanged(RadioContainer group, int checkedId) {
//                // 取的是 tag 字符串值，需转换为颜色
//                String color = (String) findComponentById(checkedId).getTag();
//                mDanmakuTextColor = RgbPalette.parse(color);
//                try {
//                    Resource resource = getResourceManager().getResource(mDanmakuTextColor);
//                    PixelMapElement pixelMap = new PixelMapElement(resource);
//                    mDanmakuCurColor.setBackground(pixelMap);
//                } catch (IOException | NotExistException e) {
//                    e.printStackTrace();
//                }
//
//            }
//        });
//    }

    /**
     * 装载弹幕，在视频按了播放键才装载
     */
//    屏蔽弹幕功能
//    private void _loadDanmaku() {
//        if (mIsEnableDanmaku) {
//            // 设置弹幕
//            mDanmakuContext = DanmakuContext.create();
//            //同步弹幕和video，貌似没法保持同步，可能我用的有问题，先注释掉- -
////            mDanmakuContext.setDanmakuSync(new VideoDanmakuSync(this));
//            if (mDanmakuParser == null) {
//                mDanmakuParser = new BaseDanmakuParser() {
//                    @Override
//                    protected Danmakus parse() {
//                        return new Danmakus();
//                    }
//                };
//            }
//            mDanmakuView.setCallback(new DrawHandler.Callback() {
//                @Override
//                public void prepared() {
//                    // 这里处理下有时调用 _resumeDanmaku() 时弹幕还没 prepared 的情况
//                    if (mVideoView.isPlaying() && !mIsBufferingStart) {
//                        mDanmakuView.start();
//                    }
//                }
//
//                @Override
//                public void updateTimer(DanmakuTimer timer) {
//                }
//
//                @Override
//                public void danmakuShown(BaseDanmaku danmaku) {
//                }
//
//                @Override
//                public void drawingFinished() {
//                }
//            });
//            mDanmakuView.enableDanmakuDrawingCache(true);
//            mDanmakuView.prepare(mDanmakuParser, mDanmakuContext);
//        }
//    }

    /**
     * 使能弹幕功能
     *
     * @return
     */
    public IjkPlayerView enableDanmaku() {
//        屏蔽弹幕功能
        mIsEnableDanmaku = true;
//        _initDanmaku();
        if (mIsAlwaysFullScreen) {
//            屏蔽弹幕功能
            _toggleDanmakuView(true);
        }
        return this;
    }

    /**
     * 使能弹幕功能
     *
     * @param isEnable
     * @return
     */
    public IjkPlayerView enableDanmaku(boolean isEnable) {
//        屏蔽弹幕功能
        mIsEnableDanmaku = isEnable;
        if (mIsEnableDanmaku) {
//            _initDanmaku();
            if (mIsAlwaysFullScreen) {
                _toggleDanmakuView(true);
            }
        }
        return this;
    }

    /**
     * 设置弹幕资源，默认资源格式需满足 bilibili 的弹幕文件格式，
     * 配合{@link #setDanmakuCustomParser}来进行自定义弹幕解析方式，{@link #setDanmakuCustomParser}必须先调用
     *
     * @param stream 弹幕资源
     * @return
     */
//    屏蔽弹幕功能
//    public IjkPlayerView setDanmakuSource(InputStream stream) {
//        if (stream == null) {
//            return this;
//        }
//        if (!mIsEnableDanmaku) {
//            throw new RuntimeException("Danmaku is disable, use enableDanmaku() first");
//        }
//        if (mDanmakuLoader == null) {
//            mDanmakuLoader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);
//        }
//        try {
//            mDanmakuLoader.load(stream);
//        } catch (IllegalDataException e) {
//            e.printStackTrace();
//        }
//        IDataSource<?> dataSource = mDanmakuLoader.getDataSource();
//        if (mDanmakuParser == null) {
//            mDanmakuParser = new BiliDanmukuParser();
//        }
//        mDanmakuParser.load(dataSource);
//        return this;
//    }

    /**
     * 设置弹幕资源，默认资源格式需满足 bilibili 的弹幕文件格式，
     * 配合{@link #setDanmakuCustomParser}来进行自定义弹幕解析方式，{@link #setDanmakuCustomParser}必须先调用
     *
     * @param uri 弹幕资源
     * @return
     */
//    屏蔽弹幕功能
//    public IjkPlayerView setDanmakuSource(String uri) {
//        if (TextTool.isNullOrEmpty(uri)) {
//            return this;
//        }
//        if (!mIsEnableDanmaku) {
//            throw new RuntimeException("Danmaku is disable, use enableDanmaku() first");
//        }
//        if (mDanmakuLoader == null) {
//            mDanmakuLoader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);
//        }
//        try {
//            mDanmakuLoader.load(uri);
//        } catch (IllegalDataException e) {
//            e.printStackTrace();
//        }
//        IDataSource<?> dataSource = mDanmakuLoader.getDataSource();
//        if (mDanmakuParser == null) {
//            mDanmakuParser = new BiliDanmukuParser();
//        }
//        mDanmakuParser.load(dataSource);
//        return this;
//    }

    /**
     * 自定义弹幕解析器，配合{@link #setDanmakuSource}使用，先于{@link #setDanmakuSource}调用
     *
     * @param parser    解析器
     * @param loader    加载器
     * @param converter 转换器
     * @return
     */
//    屏蔽弹幕功能
//    public IjkPlayerView setDanmakuCustomParser(BaseDanmakuParser parser, ILoader loader, BaseDanmakuConverter converter) {
//        mDanmakuParser = parser;
//        mDanmakuLoader = loader;
//        mDanmakuConverter = converter;
//        return this;
//    }

    /**
     * 显示/隐藏弹幕
     *
     * @param isShow 是否显示
     * @return
     */
//    屏蔽弹幕功能
//    public IjkPlayerView showOrHideDanmaku(boolean isShow) {
//        if (isShow) {
//            mIvDanmakuControl.setSelected(false);
//            mDanmakuView.show();
//        } else {
//            mIvDanmakuControl.setSelected(true);
//            mDanmakuView.hide();
//        }
//        return this;
//    }

    /**
     * 发射弹幕
     *
     * @param text   内容
     * @param isLive 是否直播
     * @return 弹幕数据
     */
//    屏蔽弹幕功能
//    public void sendDanmaku(String text, boolean isLive) {
//        if (!mIsEnableDanmaku) {
//            throw new RuntimeException("Danmaku is disable, use enableDanmaku() first");
//        }
//        if (TextTool.isNullOrEmpty(text)) {
//            new ToastDialog(mAttachActivity).setText("内容为空").show();
//            return;
//        }
//        if (!mDanmakuView.isPrepared()) {
//            new ToastDialog(mAttachActivity).setText("弹幕还没准备好").show();
//            return;
//        }
//        BaseDanmaku danmaku = mDanmakuContext.mDanmakuFactory.createDanmaku(mDanmakuType);
//        if (danmaku == null || mDanmakuView == null) {
//            return;
//        }
//        if (mDanmakuTextSize == INVALID_VALUE) {
//            mDanmakuTextSize = 25f * (mDanmakuParser.getDisplayer().getDensity() - 0.6f);
//        }
//        danmaku.text = text;
//        danmaku.padding = 5;
//        danmaku.isLive = isLive;
//        danmaku.priority = 0;  // 可能会被各种过滤器过滤并隐藏显示
//        danmaku.textSize = mDanmakuTextSize;
//        danmaku.textColor = mDanmakuTextColor;
//        danmaku.underlineColor = Color.GREEN.getValue();
//        danmaku.setTime(mDanmakuView.getCurrentTime() + 500);
//        mDanmakuView.addDanmaku(danmaku);
//
//        if (mDanmakuListener != null) {
//            if (mDanmakuConverter != null) {
//                mDanmakuListener.onDataObtain(mDanmakuConverter.convertDanmaku(danmaku));
//            } else {
//                mDanmakuListener.onDataObtain(danmaku);
//            }
//        }
//    }

    /**
     * 编辑操作前调用，会控制视频的播放状态，如在编辑弹幕前调用，配合{@link #recoverFromEditVideo()}使用
     */
    public void editVideo() {
        if (mVideoView.isPlaying()) {
            pause();
            mVideoStatus = INTERRUPT_WHEN_PLAY;
        } else {
            mVideoStatus = INTERRUPT_WHEN_PAUSE;
        }
        _hideAllView(false);
    }

    /**
     * 从编辑状态返回，如取消编辑或发射弹幕后配合{@link #editVideo()}调用
     *
     * @return 是否从编辑状态回退
     */
    public boolean recoverFromEditVideo() {
        if (mVideoStatus == NORMAL_STATUS) {
            return false;
        }
        if (mIsFullscreen) {
//            屏蔽弹幕功能
//            _recoverScreen();
        }
        if (mVideoStatus == INTERRUPT_WHEN_PLAY) {
            start();
        }
        mVideoStatus = NORMAL_STATUS;
        return true;
    }

    /**
     * 激活弹幕
     */
//    屏蔽弹幕功能
//    private void _resumeDanmaku() {
//        if (mDanmakuView != null && mDanmakuView.isPrepared() && mDanmakuView.isPaused()) {
//            if (mDanmakuTargetPosition != INVALID_VALUE) {
//                mDanmakuView.seekTo(mDanmakuTargetPosition);
//                mDanmakuTargetPosition = INVALID_VALUE;
//            } else {
//                mDanmakuView.resume();
//            }
//        }
//    }

    /**
     * 暂停弹幕
     */
//    屏蔽弹幕功能
//    private void _pauseDanmaku() {
//        if (mDanmakuView != null && mDanmakuView.isPrepared()) {
//            mDanmakuView.pause();
//        }
//    }

    /**
     * 切换弹幕的显示/隐藏
     */
//    屏蔽弹幕功能
//    private void _toggleDanmakuShow() {
//        if (mIvDanmakuControl.isSelected()) {
//            showOrHideDanmaku(true);
//        } else {
//            showOrHideDanmaku(false);
//        }
//    }

    /**
     * 切换弹幕相关控件View的显示/隐藏
     *
     * @param isShow 是否显示
     */
//    屏蔽弹幕功能
//    private void _toggleDanmakuView(boolean isShow) {
//        if (mIsEnableDanmaku) {
//            if (isShow) {
//                mIvDanmakuControl.setVisibility(VISIBLE);
//                mTvOpenEditDanmaku.setVisibility(VISIBLE);
//                mTvTimeSeparator.setVisibility(VISIBLE);
//                mDanmakuPlayerSeek.setVisibility(VISIBLE);
//                mPlayerSeek.setVisibility(HIDE);
//            } else {
//                mIvDanmakuControl.setVisibility(HIDE);
//                mTvOpenEditDanmaku.setVisibility(HIDE);
//                mTvTimeSeparator.setVisibility(HIDE);
//                mDanmakuPlayerSeek.setVisibility(HIDE);
//                mPlayerSeek.setVisibility(VISIBLE);
//            }
//        }
//
//    }

    /**
     * 从弹幕编辑状态复原界面
     */
//    屏蔽弹幕功能
//    private void _recoverScreen() {
//        // 清除焦点
//        mEditDanmakuLayout.clearFocus();
//        mEditDanmakuLayout.setVisibility(HIDE);
//        // 关闭软键盘
//        SoftInputUtils.closeSoftInput(mAttachActivity);
//        // 重新设置全屏界面UI标志位
//        _setUiLayoutFullscreen();
//        if (mDanmakuColorOptions.getWidth() != 0) {
//            _toggleMoreColorOptions();
//        }
//    }

    /**
     * 动画切换弹幕颜色选项卡显示
     */
//    屏蔽弹幕功能
//    private void _toggleMoreColorOptions() {
//        if (mBasicOptionsWidth == INVALID_VALUE) {
//            mBasicOptionsWidth = mDanmakuOptionsBasic.getWidth();
//        }
//        if (mDanmakuColorOptions.getWidth() == 0) {
//            AnimHelper.doClipViewWidth(mDanmakuOptionsBasic, mBasicOptionsWidth, 0, 300);
//            AnimHelper.doClipViewWidth(mDanmakuColorOptions, 0, mMoreOptionsWidth, 300);
//            mDanmakuMoreColorIcon.createAnimatorProperty()
//                  .moveFromX(0).moveByX(180).rotate(180).setDuration(150).setDelay(250).start();
//        } else {
//            AnimHelper.doClipViewWidth(mDanmakuOptionsBasic, 0, mBasicOptionsWidth, 300);
//            AnimHelper.doClipViewWidth(mDanmakuColorOptions, mMoreOptionsWidth, 0, 300);
//            mDanmakuMoreColorIcon.createAnimatorProperty()
//                  .moveFromX(108).moveByX(0).rotate(0).setDuration(150).setDelay(250).start();
//        }
//    }

    /**
     * ============================ 电量、时间、锁屏、截屏 ============================
     */

    // 电量显示
    private ProgressBar mPbBatteryLevel;
    // 系统时间显示
    private Text mTvSystemTime;
    // 截图按钮
    private Image mIvScreenshot;
    // 电量变化广播接收器
    private BatteryBroadcastReceiver mBatteryReceiver;
    // 锁屏状态广播接收器
    private ScreenBroadcastReceiver mScreenReceiver;
    // 网络变化广播
    private NetBroadcastReceiver mNetReceiver;
    // 判断是否出现锁屏,有则需要重新设置渲染器，不然视频会没有动画只有声音
    private boolean mIsScreenLocked = false;
    // 截图分享弹框
    private ShareDialog mShareDialog;
    // 对话框点击监听，内部和外部
    private ShareDialog.OnDialogClickListener mDialogClickListener;
    private ShareDialog.OnDialogClickListener mInsideDialogClickListener
            = new ShareDialog.OnDialogClickListener() {
        @Override
        public void onShare(PixelMap bitmap, Uri uri) {
            if (mDialogClickListener != null) {
                mDialogClickListener.onShare(bitmap, mVideoView.getUri());
            }
            File file = new File(mSaveDir, System.currentTimeMillis() + ".jpg");
            try {
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                compress(bitmap, "image/jpeg", 100, bos);
                bos.flush();
                bos.close();
                new ToastDialog(mAttachActivity).setText("保存成功，路径为:"
                        + file.getAbsolutePath()).show();
                mShareDialog.destroy();
            } catch (IOException e) {
                new ToastDialog(mAttachActivity).setText("保存本地失败").show();
            }
        }
    };
    private ShareDialog.OnDialogDismissListener mDialogDismissListener
            = new ShareDialog.OnDialogDismissListener() {
        @Override
        public void onDismiss() {
            recoverFromEditVideo();
            mShareDialog.destroy();
        }
    };
    // 截图保存路径
    private File mSaveDir;

    public static boolean compress(PixelMap pixelMap
            , String compressFormat, int quality, OutputStream outputStream) {
        if (pixelMap == null) {
            LogUtil.error("IjkPlayer", "pixelMap is empty");
            return false;
        }
        ImagePacker imagePacker = ImagePacker.create();
        ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
        packingOptions.format = compressFormat;
        packingOptions.quality = quality;
        boolean result = imagePacker.initializePacking(outputStream, packingOptions);
        if (result) {
            imagePacker.addImage(pixelMap);
            imagePacker.finalizePacking();
            return true;
        } else {
            LogUtil.error("IjkPlayer", "imagePacker failed to initial");
            return false;
        }
    }

    /**
     * 初始化电量、锁屏、时间处理
     */
    private void _initReceiver(Context context) {
        mPbBatteryLevel = (ProgressBar) findComponentById(ResourceTable.Id_pb_battery);
        mTvSystemTime = (Text) findComponentById(ResourceTable.Id_tv_system_time);
        mTvSystemTime.setText(StringUtils.getCurFormatTime());

        MatchingSkills screenSkill = new MatchingSkills();
        screenSkill.addEvent(COMMON_EVENT_SCREEN_ON); // 亮屏事件
        CommonEventSubscribeInfo screenInfo = new CommonEventSubscribeInfo(screenSkill);

        MatchingSkills batterySkill = new MatchingSkills();
        batterySkill.addEvent(COMMON_EVENT_BATTERY_CHANGED); // 电池事件
        CommonEventSubscribeInfo batteryInfo = new CommonEventSubscribeInfo(batterySkill);

        MatchingSkills networkSkill = new MatchingSkills();
        networkSkill.addEvent(COMMON_EVENT_WIFI_CONN_STATE); // 网络事件
        CommonEventSubscribeInfo networkInfo = new CommonEventSubscribeInfo(batterySkill);

        mBatteryReceiver = new BatteryBroadcastReceiver(batteryInfo);
        mScreenReceiver = new ScreenBroadcastReceiver(screenInfo);
        mNetReceiver = new NetBroadcastReceiver(networkInfo);

        //注册接受广播
        try {
            CommonEventManager.subscribeCommonEvent(mBatteryReceiver);
            CommonEventManager.subscribeCommonEvent(mScreenReceiver);
            CommonEventManager.subscribeCommonEvent(mNetReceiver);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        mIvScreenshot = (Image) findComponentById(ResourceTable.Id_iv_screenshot);
        mIvScreenshot.setClickedListener(this);
        if (SDCardUtils.isAvailable()) {
            _createSaveDir(SDCardUtils.getRootPath(context)
                    + File.separator + "IjkPlayView");
        }
    }

    /**
     * 截图
     */
    private void _doScreenshot() {
        editVideo();
        try {
            Resource resource = getResourceManager().getResource(ResourceTable.Media_picture_test);
            ImageSource imageSource = ImageSource.create(resource, null);
            PixelMap pixelmap = imageSource.createPixelmap(null);
            _showShareDialog(pixelmap);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        }
//        _showShareDialog(mVideoView.getScreenshot());
    }

    /**
     * 显示对话框
     *
     * @param bitmap
     */
    private void _showShareDialog(PixelMap bitmap) {
        mShareDialog = null;
        if (mShareDialog == null) {
            mShareDialog = new ShareDialog(mAttachActivity);
            mShareDialog.setClickListener(mInsideDialogClickListener);
            mShareDialog.setDismissListener(mDialogDismissListener);
            if (mDialogClickListener != null) {
                mShareDialog.setShareMode(true);
            }
        }
        mShareDialog.setScreenshotPhoto(bitmap);
        //mShareDialog.show(mAttachActivity.getSupportFragmentManager(), "share");
        mShareDialog.show();
    }

    /**
     * 设置截图分享监听
     *
     * @param dialogClickListener
     * @return
     */
    public IjkPlayerView setDialogClickListener(
            ShareDialog.OnDialogClickListener dialogClickListener) {
        mDialogClickListener = dialogClickListener;
        if (mShareDialog != null) {
            mShareDialog.setShareMode(true);
        }
        return this;
    }

    /**
     * 创建目录
     *
     * @param path
     */
    private void _createSaveDir(String path) {
        mSaveDir = new File(path);
        if (!mSaveDir.exists()) {
            mSaveDir.mkdirs();
        } else if (!mSaveDir.isDirectory()) {
            mSaveDir.delete();
            mSaveDir.mkdirs();
        }
    }

    /**
     * 设置截图保存路径
     *
     * @param path
     */
    public IjkPlayerView setSaveDir(String path) {
        _createSaveDir(path);
        return this;
    }

    /**
     * 接受电量改变广播
     */
    class BatteryBroadcastReceiver extends CommonEventSubscriber {

        // 低电量临界值
        private static final int BATTERY_LOW_LEVEL = 15;

        public BatteryBroadcastReceiver(CommonEventSubscribeInfo subscribeInfo) {
            super(subscribeInfo);
        }

        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            LogUtil.error("IjkPlayerView.BatteryBroadcastReceiver", "commonEventData.getIntent().getAction(): " + commonEventData.getIntent().getAction());
            // 接收电量变化信息
            if (commonEventData.getIntent().getAction().equals(COMMON_EVENT_BATTERY_CHANGED)) {
                BatteryInfo batteryInfo = new BatteryInfo();
                int capacity = batteryInfo.getCapacity();
                int scale = commonEventData.getIntent().getIntParam("scale", 100);
                // 电量百分比
                int curPower = capacity * 100 / scale;
                BatteryInfo.BatteryChargeState chargingStatus = batteryInfo.getChargingStatus();
                // SecondaryProgress 用来展示低电量，Progress 用来展示正常电量

                try {
                    if (chargingStatus.equals(BatteryInfo.BatteryChargeState.FULL)
                            || chargingStatus.equals(BatteryInfo.BatteryChargeState.ENABLE)) {
                        mPbBatteryLevel.setViceProgress(0);
//                        mPbBatteryLevel.setProgressValue(curPower);
                        PixelMapElement pixelMapElement = new PixelMapElement(getResourceManager()
                                .getResource(ResourceTable.Media_ic_battery_charging));
                        mPbBatteryLevel.setBackground(pixelMapElement);
                    } else if (curPower < BATTERY_LOW_LEVEL) {
                        mPbBatteryLevel.setViceProgress(0);
                        mPbBatteryLevel.setProgressValue(curPower);
                        PixelMapElement pixelMapElement = new PixelMapElement(getResourceManager()
                                .getResource(ResourceTable.Media_ic_battery_red));
                        mPbBatteryLevel.setBackground(pixelMapElement);
                    } else {
                        mPbBatteryLevel.setViceProgress(0);
                        mPbBatteryLevel.setProgressValue(curPower);
                        PixelMapElement pixelMapElement = new PixelMapElement(getResourceManager()
                                .getResource(ResourceTable.Media_ic_battery));
                        mPbBatteryLevel.setBackground(pixelMapElement);
                    }
                } catch (IOException | NotExistException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 锁屏状态广播接收者
     */
    private class ScreenBroadcastReceiver extends CommonEventSubscriber {

        public ScreenBroadcastReceiver(CommonEventSubscribeInfo subscribeInfo) {
            super(subscribeInfo);
        }

        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            if (COMMON_EVENT_SCREEN_OFF.equals(commonEventData.getIntent().getAction())) {
                mIsScreenLocked = true;
            }
        }
    }

    private boolean mIsNetConnected;

    public class NetBroadcastReceiver extends CommonEventSubscriber {
        public NetBroadcastReceiver(CommonEventSubscribeInfo subscribeInfo) {
            super(subscribeInfo);
        }

        @Override
        public void onReceiveEvent(CommonEventData commonEventData) {
            NetManager netManager = NetManager.getInstance(getContext());
            if (COMMON_EVENT_WIFI_CONN_STATE.equals(commonEventData.getIntent().getAction())) {
                mIsNetConnected = NetWorkUtils.isNetworkAvailable(mAttachActivity);
            }
        }
    }

    //==============================================================================================
    //-------------------------------------以下为手势逻辑--------------------------------------------
    //==============================================================================================
    @Override
    public void onGestureBegin(int type) {
        //进度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_FULL_X) {
            tempPosition = mVideoView.getCurrentPosition();
        }

        //亮度
        if (type == HandleTouchEvent.GestureEvent.TOUCH_LEFT_Y) {
            tempBrightness = mAttachActivity.getWindow().getLayoutConfig().get().windowBrightness;
            if (tempBrightness < 0) {
                try {//系统亮度 不能activity取
                    tempBrightness = Integer.parseInt(SystemSettings.getValue(DataAbilityHelper.creator(getContext()), SystemSettings.Display.SCREEN_BRIGHTNESS_STATUS));
                } catch (Exception e) {
                    e.printStackTrace();
                    tempBrightness = 0;
                }
            }
        }
        //音量
        if (type == HandleTouchEvent.GestureEvent.TOUCH_RIGHT_Y) {
        }
    }

    //调节前的值 亮度退出全屏应原样
    private int tempPosition;
    private float tempBrightness;

    @Override
    public void onGestureChange(int type, float level) {
        if (!mIsForbidTouch && !mIsNeverPlay) {
            //进度
            if (type == HandleTouchEvent.GestureEvent.TOUCH_FULL_X) {
                int duration = mVideoView.getDuration();
                if (duration <= 1)
                    return;
                //拖动开始慢 后面快
                int delta = (int) (level * Math.abs(level) * duration);
                if (delta < -tempPosition) {
                    delta = -tempPosition;
                }
                if (delta > duration - tempPosition) {
                    delta = duration - tempPosition;
                }
                _onProgressSlide(delta);
            }

            //亮度
            if (type == HandleTouchEvent.GestureEvent.TOUCH_LEFT_Y) {
                _onBrightnessSlide(level);
            }
            //音量
            if (type == HandleTouchEvent.GestureEvent.TOUCH_RIGHT_Y) {
                _onVolumeSlide(level);
            }
        }

    }

    @Override
    public void onGestureEnd(int type, float level) {
        if (!mIsForbidTouch && !mIsNeverPlay) {
            if (type == HandleTouchEvent.GestureEvent.TOUCH_DOUBLE_C) {
                _togglePlayStatus();
            }

            //进度
            if (type == HandleTouchEvent.GestureEvent.TOUCH_FULL_X) {
                seekTo((int) mTargetPosition);
                mTvFastForward.setVisibility(HIDE);
            }

            //亮度
            if (type == HandleTouchEvent.GestureEvent.TOUCH_LEFT_Y) {
                mTvBrightness.setVisibility(HIDE);
            }
            //音量
            if (type == HandleTouchEvent.GestureEvent.TOUCH_RIGHT_Y) {
                mTvVolume.setVisibility(HIDE);
            }
        }
    }

    /**
     * ==============弹幕功能设置==============
     */


    private IDanmakuView mDanmakuView;
    private DanmakuContext danmakuContext;
    private BaseDanmakuParser mParser;
    private Image cancelButton;
    private TextField textField;
    private Image sendButton;
    private Text mTvOpenEditDanmaku;
    private Text mTvTimeSeparator;
    private Slider mDanmakuPlayerSeek;

    // 弹幕显示/隐藏按钮
    private Image mIvDanmakuControl;
    // 是否使能弹幕
    private boolean mIsEnableDanmaku = false;
    // 弹幕编辑布局
    private Component mEditDanmakuLayout;

    public void initDanmakuView() {
        mEditDanmakuLayout = findComponentById(ResourceTable.Id_ll_edit_danmaku);
        cancelButton = (Image) findComponentById(ResourceTable.Id_iv_cancel_send);
        sendButton = (Image) findComponentById(ResourceTable.Id_iv_do_send);
        mTvOpenEditDanmaku = (Text) findComponentById(ResourceTable.Id_tv_open_edit_danmaku);
        mIvDanmakuControl = (Image) findComponentById(ResourceTable.Id_iv_danmaku_control);
        mTvTimeSeparator = (Text) findComponentById(ResourceTable.Id_tv_separator);

        mDanmakuPlayerSeek = (Slider) findComponentById(ResourceTable.Id_danmaku_player_seek);
        mDanmakuPlayerSeek.setMaxValue(MAX_VIDEO_SEEK);
        mDanmakuPlayerSeek.setValueChangedListener(mSeekListener);

        mIvDanmakuControl.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                if (mDanmakuView.isShown()) {
                    mDanmakuView.hide();
                    mIvDanmakuControl.setPixelMap(ResourceTable.Media_ic_danmaku_closed);
                } else {
                    mDanmakuView.show();
                    mIvDanmakuControl.setPixelMap(ResourceTable.Media_ic_danmaku_open);
                }
            }
        });

    }

    /**
     * 切换弹幕相关控件View的显示/隐藏
     *
     * @param isShow 是否显示
     */
    private void _toggleDanmakuView(boolean isShow) {
        if (mIsEnableDanmaku) {
            if (isShow) {
                mIvDanmakuControl.setVisibility(VISIBLE);
                mTvOpenEditDanmaku.setVisibility(VISIBLE);
                mTvTimeSeparator.setVisibility(VISIBLE);
                mDanmakuPlayerSeek.setVisibility(VISIBLE);
                mPlayerSeek.setVisibility(HIDE);
            } else {
                mIvDanmakuControl.setVisibility(HIDE);
                mTvOpenEditDanmaku.setVisibility(HIDE);
                mTvTimeSeparator.setVisibility(HIDE);
                mDanmakuPlayerSeek.setVisibility(HIDE);
                mPlayerSeek.setVisibility(VISIBLE);
            }
        }

    }


    //设置数据源
    private BaseDanmakuParser createParser(InputStream stream) {

        if (stream == null) {
            return new BaseDanmakuParser() {

                @Override
                protected Danmakus parse() {
                    return new Danmakus();
                }
            };
        }

        ILoader loader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);

        try {
            loader.load(stream);
        } catch (IllegalDataException e) {
            e.printStackTrace();
        }
        BaseDanmakuParser parser = new BiliDanmukuParser();
        IDataSource<?> dataSource = loader.getDataSource();
        parser.load(dataSource);
        return parser;

    }

    public void initDamukuView(String source) {
        WindowManager windowManager = WindowManager.getInstance();
        Window window = windowManager.getTopWindow().get();
        WindowManager.LayoutConfig layoutConfig = new WindowManager.LayoutConfig();
        layoutConfig.flags = WindowManager.LayoutConfig.MARK_ALLOW_LAYOUT_COVER_SCREEN;
        layoutConfig.flags = layoutConfig.flags | WindowManager.LayoutConfig.MARK_FULL_SCREEN;
        layoutConfig.windowBrightness = 1.0f;
        window.setLayoutConfig(layoutConfig);
        window.addFlags(WindowManager.LayoutConfig.MARK_LAYOUT_ATTACHED_IN_DECOR);
        window.addFlags(WindowManager.LayoutConfig.MARK_LAYOUT_INSET_DECOR);

        System.out.println(" height ====+++++++++============= : " + layoutConfig.height);
        System.out.println(" width  ====+++++++++============= : " + layoutConfig.width);
        window.setBackgroundColor(new RgbColor(0xB7B208));

        DanmakuView danmakuView = (DanmakuView) findComponentById(ResourceTable.Id_sv_danmaku);
        danmakuView.addDrawTask(null);
        danmakuView.setLayoutRefreshedListener(null);

        // 设置最大显示行数
        HashMap<Integer, Integer> maxLinesPair = new HashMap<Integer, Integer>();
        maxLinesPair.put(BaseDanmaku.TYPE_SCROLL_RL, 5); // 滚动弹幕最大显示5行
        // 设置是否禁止重叠
        HashMap<Integer, Boolean> overlappingEnablePair = new HashMap<Integer, Boolean>();
        overlappingEnablePair.put(BaseDanmaku.TYPE_SCROLL_RL, true);
        overlappingEnablePair.put(BaseDanmaku.TYPE_FIX_TOP, true);

        mDanmakuView = (IDanmakuView) findComponentById(ResourceTable.Id_sv_danmaku);
        danmakuContext = DanmakuContext.create();
        danmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN, 3)   //设置描边样式
                .setDuplicateMergingEnabled(false)  //设置不合并相同内容弹幕
                .setScrollSpeedFactor(0.9f)         //设置弹幕滚动速度缩放比例，越大速度越慢
                .setScaleTextSize(1.2f)             //设置字体缩放比例
//                .setCacheStuffer(new SpannedCacheStuffer(), mCacheStufferAdapter) // 图文混排使用SpannedCacheStuffer
                .setCacheStuffer(new SimpleTextCacheStuffer(), mCacheStufferAdapter)        //===========这里修改为使用SimpleTextCacheStuffer
//        .setCacheStuffer(new BackgroundCacheStuffer())  // 绘制背景使用BackgroundCacheStuffer
                .setMaximumLines(maxLinesPair)              //设置最大行数策略
                .preventOverlapping(overlappingEnablePair)  //设置禁止重叠策略
                .setDanmakuMargin(40);

        if (mDanmakuView != null) {

            InputStream stream = null;
            try {
                stream = this.getResourceManager().getRawFileEntry(source).openRawFile();
            } catch (IOException e) {
                e.printStackTrace();
            }

            mParser = createParser(stream);

            mDanmakuView.setCallback(new master.flame.danmaku.controller.DrawHandler.Callback() {
                @Override
                public void updateTimer(DanmakuTimer timer) {
                }

                @Override
                public void drawingFinished() {

                }

                @Override
                public void danmakuShown(BaseDanmaku danmaku) {
                }

                @Override
                public void prepared() {
                    mDanmakuView.start();
                }
            });

            mDanmakuView.setOnDanmakuClickListener(new IDanmakuView.OnDanmakuClickListener() {

                @Override
                public boolean onDanmakuClick(IDanmakus danmakus) {
                    BaseDanmaku latest = danmakus.last();
                    if (null != latest) {
                        return true;
                    }
                    return false;
                }

                @Override
                public boolean onDanmakuLongClick(IDanmakus danmakus) {
                    return false;
                }

                @Override
                public boolean onViewClick(IDanmakuView view) {
//                    mMediaController.setVisibility(View.VISIBLE);
                    return false;
                }
            });
            mDanmakuView.prepare(mParser, danmakuContext);
            mDanmakuView.showFPS(true);
            mDanmakuView.enableDanmakuDrawingCache(true);
            mDanmakuView.show();
        }

    }

    public BaseCacheStuffer.Proxy mCacheStufferAdapter = new BaseCacheStuffer.Proxy() {

//        private Drawable mDrawable;

        @Override
        public void prepareDrawing(final BaseDanmaku danmaku, boolean fromWorkerThread) {
//            if (danmaku.text instanceof Spanned) { // 根据你的条件检查是否需要需要更新弹幕
//                // FIXME 这里只是简单启个线程来加载远程url图片，请使用你自己的异步线程池，最好加上你的缓存池
//                new Thread() {
//
//                    @Override
//                    public void run() {
//                        String url = "http://www.bilibili.com/favicon.ico";
//                        InputStream inputStream = null;
//                        Drawable drawable = mDrawable;
//                        if(drawable == null) {
//                            try {
//                                URLConnection urlConnection = new URL(url).openConnection();
//                                inputStream = urlConnection.getInputStream();
//                                drawable = BitmapDrawable.createFromStream(inputStream, "bitmap");
//                                mDrawable = drawable;
//                            } catch (MalformedURLException e) {
//                                e.printStackTrace();
//                            } catch (IOException e) {
//                                e.printStackTrace();
//                            } finally {
//                                IOUtils.closeQuietly(inputStream);
//                            }
//                        }
//                        if (drawable != null) {
//                            drawable.setBounds(0, 0, 100, 100);
//                            SpannableStringBuilder spannable = createSpannable(drawable);
//                            danmaku.text = spannable;
//                            if(mDanmakuView != null) {
//                                mDanmakuView.invalidateDanmaku(danmaku, false);
//                            }
//                            return;
//                        }
//                    }
//                }.start();
//            }
        }

        @Override
        public void releaseResource(BaseDanmaku danmaku) {
            // TODO 重要:清理含有ImageSpan的text中的一些占用内存的资源 例如drawable
        }
    };

    public void addDanmaku(String textString, boolean islive) {
        BaseDanmaku danmaku = danmakuContext.mDanmakuFactory.createDanmaku(BaseDanmaku.TYPE_SCROLL_RL);
        if (danmaku == null || mDanmakuView == null) {
            return;
        }

        danmaku.text = textString + "-> 系统时间：" + System.nanoTime();
        danmaku.padding = 5;
        danmaku.priority = 0;  // 可能会被各种过滤器过滤并隐藏显示
        danmaku.isLive = islive;
        danmaku.setTime(mDanmakuView.getCurrentTime() + 1200);
        danmaku.textSize = 25f * (mParser.getDisplayer().getDensity() - 0.6f);
        danmaku.textColor = Color.RED.getValue();
        danmaku.textShadowColor = Color.WHITE.getValue();

        danmaku.borderColor = Color.GREEN.getValue();
        System.out.println("addDanmaku: " + danmaku.text);
        mDanmakuView.addDanmaku(danmaku);
    }


}
